useResource$() - Explicit Reactivity

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 fetch and display data from the server. When fetching data the application can be in one of three states:

  • pending: the data is being fetched from the server => Render loading... indicator.
  • rejected: the data could not be fetched from the server due to an error => Render the error.
  • resolved: the data has successfully been fetched from the server => Render the data.

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

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 (lazily) provided and will be aborted when this
    // function re-runs, allowing you to cancel pending operations.
    return getRepositories(org, abortSignal);
  });

The useAsync$() function returns an AsyncSignal, 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 and .error reactive properties to allow you to render different content depending if the resource is pending, resolved or rejected.

During SSR, the rendering will pause until the AsyncSignal has loaded so it will always render as either resolved or rejected.

{reposResource.loading && <div>Loading...</div> ? reposResource.error ? <div>Error: {reposResource.error}</div> : <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