Skip to content
On this page

createQuery

Formulae

INFO

Option initialData available in all overloads since v0.3

createQuery({ handler, initialData? })

Creates Query based on given asynchronous function.

ts
const languagesQuery = createQuery({
  handler: async () => {
    const response = await fetch('https://api.salo.com/languages.json');

    return response.json();
  },
});

createQuery({ effect, validate?, initialData? })

Creates Query based on given Effect.

Usage of Effect instead of simple asynchronous function allows you to declare types of possible errors statically that will be passed to Query.

This form allows you to dynamically validate received data using Validator in the optional validate field.

ts
const languagesQuery = createQuery({
  effect: createEffect<Response, void, EmptyLanguagesError>(async () => {
    const response = await fetch('https://api.salo.com/languages.json');

    const data = await response.json();

    if (!data.languages) {
      throw new EmptyLanguagesError();
    }

    return data.languages;
  }),
});

// typeof languagesQuery.$error === Store<EmptyLanguagesError | null>

createQuery({ effect, contract, validate?, initialData? })

Creates Query based on given Effect.

Contract allows you to validate the response and decide how your application should treat it — as a success response or as a failed one. Furthermore, this form allows you to dynamically validate received data using Validator in the optional validate field.

ts
const languagesQuery = createQuery({
  effect: fetchLanguagesFx,
  contract: {
    // Our API can return empty array of languages, we consider it as an invalid data
    isData: (response) => response.languages?.length > 0,
    // Array with description of reasons why data is invalid
    getErrorMessages: (response) => ['Expected array with at least one language, but got empty array'],
  },
});

/* typeof languagesQuery.$error === Store<
 *   | InvalidDataError 👈 validation failed, languages list is empty
 *   | string[] 👈 API errors from response.errors
 *   | null 👈 no errors
 * >
 */

createQuery({ effect, contract?, validate?, mapData: Function, initialData? })

Creates Query based on given Effect. Result of the effect will be validated against the Contract and the optional Validator. Invalid result will cause the Query to fail.

A valid data is passed to mapData callback as well as original parameters of the Query, result of the callback will be treated as a result of the Query.

ts
const languagesQuery = createQuery({
  effect: fetchLanguagesFx,
  contract: languagesContract,
  mapData({ result: languages, params }) {
    return {
      availableLanguages: languages,
      languageCanBeSelected: languages.length > 1,
    };
  },
});

/* typeof languagesQuery.$data === Store<{
 *   availableLanguages: string[],
 *   languageCanBeSelected: boolean,
 * }>
 */

createQuery({ effect, contract?, validate?, mapData: { source, fn }, initialData? })

Creates Query based on given Effect. Result of the effect will be validated against the Contract and the optional Validator. Invalid result will cause the query to fail.

A valid data is passed to mapData.fn callback as well as original parameters of the Query and current value of mapData.source Store, result of the callback will be treated as a result of the Query.

ts
const $minimalLanguagesCount = createStore(1);

const languagesQuery = createQuery({
  effect: fetchLanguagesFx,
  contract: languagesContract,
  mapData: {
    // Current value of $minimalLanguagesCount will be passed to `fn` as a third argument
    source: $minimalLanguagesCount,
    fn({ result: languages, params }, minimalLanguagesCount) {
      return {
        availableLanguages: languages,
        languageCanBeSelected: languages.length > minimalLanguagesCount,
      };
    },
  },
});

/* typeof languagesQuery.$data === Store<{
 *   availableLanguages: string[],
 *   languageCanBeSelected: boolean,
 * }>
 */

Released under the MIT License.