# Remote data

To work with remote data, you need to implement the source function. For convenience, you can use the DataGridSource<TRow> type to make sure you've implement the function correctly.

export type DataGridSource<TRow> =
  | ((params: DataGridSourceParameters<TRow>) 
      => Promise<DataGridPage<TRow> | null>)
  | TRow[];

// Parameters for the remote data function
export type DataGridSourceParameters<TRow> = {
  /** The current page number. */
  page: number;
  /** The number of items per page. */
  items: number;
  /** A search query. */
  search?: string;
  /** The sort key. */
  sort?: keyof TRow;
  /** The sort order. */
  order?: SortDirection;
  /** Any extra filters. Will be converted to query parameters as-is. */
  filters?: CustomFilters;
  /** Any extra parameters required by the `source`. */
  params?: { [param: string]: string };
};

This function returns a promise that resolves to a DataGridPage<TRow> or null if the request fails. The DataGridPage<TRow> type looks like this:

export type SortDirection = 'asc' | 'desc';

export type DataGridPage<TRow> = {
  data: TRow[];
  page: number;
  items: number;
  search?: string,
  sort?: {
    column: symbol;
    direction: SortDirection;
  };
  total?: {
    items: number;
    filteredItems: number;
    pages: number;
  }
};

# Example

The most common source for remote data is an API. In this example, we will look at a REST API. We'll use the Book type we've been using again, and assume we're querying a library for the books they have available.

# Our fake library endpoint

We'll build our DataSource function piece-by-piece. We start by looking at our REST endpoint. We'll say the base URL is https://api.library.fake/v1/ and our endpoint is located at /books. The library has documented their REST API well, so we know that we can filter the result using URL query parameters:

ParameterResult
N/A Returns a list of 20 books, sorted by author.
?limit=10 Limits the number of results to 10.
?skip=20 Skips the first 20 results.
?q=[QUERY] Searches for the string [QUERY] in the author and title fields.
?sort=[COLUMN] Sorts the books by [COLUMN] in ascending order.
?order=desc Sorts the books by [QUERY] in descending order.

By combining these parameters, we can search through the books the library offers fairly thoroughly. All we have to do is translate the parameters provided by svelte-datagrid to the library's query parameters.

# Building our data source function

We'll start by creating a function and typing it using our DataGridSource<TRow> type.

async function getBooks(params: DataGridSourceParameters<Book>) {
  // function body
} satisfies DataGridSource<Book>;

Next, well start constructing our endpoint URL. The easiest way to make sure query parameters are added correctly is by using the URL class, so we'll create a URL object first:

async function getBooks(params: DataGridSourceParameters<Book>) {
  const baseUrl = new URL('https://api.library.fake/v1/books');
} satisfies DataGridSource<Book>;

# Query parameters

We'll look at adding query parameters to the URL next. svelte-datagrid provides a handy buildFetchUrl method that should be able to deal with most configurations.

async function getBooks(params: DataGridSourceParameters<Book>) {
  const baseUrl = new URL('https://api.library.fake/v1/books');

  const fetchUrl = buildFetchUrl(baseUrl, params);

  const response = await fetch(fetchUrl);
} satisfies DataGridSource<Book>;

By default, this method is configured to work with a page number based pagination system. However, our example uses a skip-based system, where we supply number of items in the data set to skip.

We can configure the function to use the skip system by passing the options parameter with pagination set to 'skip':

async function getBooks(params: DataGridSourceParameters<Book>) {
  const baseUrl = new URL('https://api.library.fake/v1/books');

  const options: FetchUrlOptions<Book> = { pagination: 'skip' };
  const fetchUrl = buildFetchUrl(baseUrl, params, options);

  const response = await fetch(fetchUrl);
} satisfies DataGridSource<Book>;