Fetching resource on state change

For this tutorial, we would like to fetch the list of repositories for a given GitHub organization. To aid you, we have added the getRepositories() function to the bottom of the file. Your task is to use the getRepositories() function to fetch the list of repositories whenever the user updates the org input.

Qwik provides useAsync$() to help you lazily fetch and display data from the server. It returns an AsyncSignal<T> which has these states:

  • loading: the data is being fetched from the server => Render loading... indicator. .loading is true while data is being fetched.
  • resolved: the data has successfully been fetched from the server => Render the data. .value contains the last fetched data or the initial value.
  • errored: the data could not be fetched from the server due to an error => Render the error. .error contains the error, if any.

These states are reactive, meaning that if you use them and they change, your component will automatically re-render to reflect the new state.

Note that when reading .loading, it will trigger the actual loading of the data. So you typically won't have to trigger the load manually.

Fetching data

Use useAsync$() to set up how the data is fetched from the server.

  const reposResource = useAsync$<string[]>(({ track, abortSignal }) => {
    // We need a way to re-run fetching data whenever the `github.org` changes.
    // Use `track` to trigger re-running of this data fetching function.
    const org = track(githubOrg);
 
    // The abortSignal is automatically provided and will be aborted when this
    // function re-runs, allowing you to cancel pending operations.
 
    // Fetch the data and return the promises.
    return getRepositories(org, abortSignal);
  });

The useAsync$() function returns an AsyncSignal object, which is reactive state that can be serialized by Qwik. The useAsync$() function allows you to track store properties so that the useAsync$() function can be reactive on store changes. The abortSignal allows you to cancel pending operations when the function re-runs. Finally, the useAsync$() function returns a promise that will resolve to the value.

Rendering data

The AsyncSignal provides the .loading, .error, and .value reactive properties to allow you to render different content depending if the resource is pending, resolved or rejected.

On the server, rendering pauses until the resource is resolved and will always render as either resolved or rejected. (On the client, all states including pending are rendered.)

{reposResource.loading && <div>Loading...</div>}
{reposResource.error && <div>Error: {reposResource.error.message}</div>}
{reposResource.value && <div>{reposResource.value}</div>}

SSR vs Client

Notice that the same code can render on both server and client (with slightly different behavior, which skips the pending state rendering on the server.)

Edit Tutorial