Skip to content

Fetching a list of documents

Nikhil Kothari edited this page Apr 19, 2024 · 2 revisions

useFrappeGetDocList

To fetch a list of documents of a certain DocType, use the useFrappeGetDocList hook.

This hook makes a GET API request to the /api/resource/:doctype endpoint.

Internally, the hook uses useSWR to cache the data.

Simple Usage

const { data, isLoading, error } = useFrappeGetDocList("My DocType Name")

The hook manages loading and error states as well as caches the data locally. You can pass in additional options to filter, sort and paginate the data.

The request is fired when the components mounts. You can change this behaviour via SWR configuration.


It returns the following parameters in an object:

data

data can either be undefined or an array of string (if no fields is passed in arguments - more on this below) or an array of objects.

data is undefined when the request is either in-flight (loading) or if an error occurred when making the request.

isLoading

isLoading is a boolean. Use this to show a loading indicator to your users.

As the name suggests, it will be true when the request is in-flight. It will be false when the data is returned or if an error occurs.

error

error can be undefined or of type FrappeError if an error occurs when making the request. Use this to show error states to your users.

The hook also returns the mutate and isValidating variables.


Arguments

The hook takes the following arguments:

Parameters:

No. Variable type Required Description
1. doctype string Name of the doctype
2. args GetDocListArgs - optional parameter (object) to sort, filter, paginate and select the fields that you want to fetch.
3. swrKey Key - SWR Key (used for managing cache)
4. options SWRConfiguration - SWR Configuration Options

Select fields, filter, sort, group, and paginate

args = {
    /** Fields to be fetched - array of strings */
    fields?: string[];
    /** Filters to be applied - SQL AND operation */
    filters?: Filter[];
    /** Filters to be applied - SQL OR operation */
    orFilters?: Filter[];
    /** Fetch from nth document in filtered and sorted list. Used for pagination  */
    limit_start?: number;
    /** Number of documents to be fetched. Default is 20  */
    limit?: number;
    /** Sort results by field and order  */
    orderBy?: {
        field: string;
        order?: 'asc' | 'desc';
    };
    /** Group the results by particular field */
    groupBy?: string;
}

Examples

Fetch 20 documents (only IDs)

Since no fields were passed, data returned is an array of strings

export const UserList = () => {
  const { data, error, isLoading } = useFrappeGetDocList('User');

  return <div>
    {isLoading ? <Loader /> : null}

    {error ? <ErrorBanner error={error} /> : null}

    {data ?
      <ul>
        {data.map((username) => (
          <li>{username}</li>
        ))}
      </ul>
      : null}

  </div>
};

Selecting fields

This will still fetch the latest 20 records in the list

export const UserList = () => {
  const { data, error, isLoading } = useFrappeGetDocList('User', {
    // We pass an array of strings in fields to fetch more fields
    fields: ['name', 'username']
  });

  return <div>
    {isLoading ? <Loader /> : null}

    {error ? <ErrorBanner error={error} /> : null}

    {data ?
      <ul>
        {data.map((user) => (
          <li>{user.username} - {user.name}</li>
        ))}
      </ul>
      : null}

  </div>
};

Filtering

filters and or_filters should be an array - where each filters is of the format: [field, operator, value]

const { data, error, isLoading } = useFrappeGetDocList('User', 
  {
    fields: ['name', 'username'],
    filters: [['enabled', '=', 1], ['name', 'like', 'A%']],
  }
);

Ordering

orderBy is an object with a field and order like:

const { data, error, isLoading } = useFrappeGetDocList('User', 
  {
    fields: ['name', 'username'],
    filters: [['enabled', '=', 1], ['name', 'like', 'A%']],
    
    orderBy: {
      field: 'name',
      order: 'asc'
    }
  }
);

Limiting number of records

This will fetch 50 records instead of 20

const { data, error, isLoading } = useFrappeGetDocList('User', 
  {
    fields: ['name', 'username'],
    filters: [['enabled', '=', 1], ['name', 'like', 'A%']],
    orderBy: {
      field: 'name',
      order: 'asc'
    },

    limit: 50
  }
);

Pagination

You can use offset based pagination to fetch records after a certain number of records.

For example, to fetch the next 50 records, use the following:

const { data, error, isLoading } = useFrappeGetDocList('User', 
  {
    fields: ['name', 'username'],
    filters: [['enabled', '=', 1], ['name', 'like', 'A%']],
    orderBy: {
      field: 'name',
      order: 'asc'
    },
    limit: 50,

    limit_start: 50
  }
);