DEV Community

Gil Fink
Gil Fink

Posted on • Originally published at gilfink.Medium on

Using QwikCity Loaders to Load Data

One of the new features that QwikCity include is the new loaders features. What is a QwikCity loader? How can you use it?

In this post you will get the answers to these questions.

What is a QwikCity Loader?

A loader is a new feature that was added to QwikCity lately. A loader purpose is enable Qwik components to load data from the server in a seamless way. You don’t need to write fetch code or use the XmlHttpRequest object or even expose an endpoint for some piece of data. Just write a loader with the loader syntax and then you can use it as part of your component. QwikCity will do the heavy lifting of fetching the data on the server and have it ready for the component usage.

Sounds great, so how can I create a loader?

Creating a QwikCity Loader

Creating a loader is as simple as to use the loader$ higher order function. The loader$ function receives a callback function that is going to be used in the server to load the data. The callback function’s returned value will be added to the consuming Qwik component and you will be able to use it when the component is mounted.

Loader Creation Example

Let’s say we have a simple productsDB file with the following code:

export interface Product {
  id: number;
  name: string;
  description: string;
}

export const products: Product[] = [
  {
    id: 1,
    name: "Wood Table",
    description: "A wood table",
  },
  {
    id: 2,
    name: "Plastic Table",
    description: "A plastic table",
  },
];
Enter fullscreen mode Exit fullscreen mode

If I want to create a loader that will fetch all the products data, it might look like:

import { products } from "~/data/productsDB";

export const useProductsLoader = loader$(() => {
  return products;
});
Enter fullscreen mode Exit fullscreen mode

Pay attention to the usage of the use* convention in the loader name.

Now that you have the loader’s code, how can you consume it from a Qwik component?

This is straight forward. Just run the loader function in the component code and use the returned value.

Loader Usage Example

export default component$(() => {
  const products = useProductsLoader();

  return (
    <div>
      <ul>
        {products.value.map((product) => {
          return (
            <li>
              <div>{product.name}</div>
              <div>{product.description}</div>
            </li>
          );
        })}
      </ul>
    </div>
  );
});
Enter fullscreen mode Exit fullscreen mode

As you can see, I use the previous loader as a function. Then, in the rendering code I use the products.value to get a hold of the products data and render them.

The code I showed is simple but what else can you do with a loader?

Use the loader context.

The Loader Context

Loaders run in a context of a QwikCity RequestEvent. That means you can have the request context as an argument of the callback function. What can you do with this context?

You can investigate the request headers, url, cookies, params and more. All this content can help you to do decisions about which data to send back and in which conditions.

Let’s look at a simple usage example:

export const useProductsLoader = loader$(({ url, method }) => {
  if (method === 'GET') {
    return { url, products };
  }
  return { url, products: [] };
});
Enter fullscreen mode Exit fullscreen mode

The previous loader was refactored to return the url with the products if the request was a HttpGet else to return the url with an empty array. I know it’s something that you probably won’t do in real world scenario, but for now it’s just showing you how to use the context. In real world, you might examine the cookies to see if a user is authenticated, check the params for existence of some specific parameter such as an id and etc.

The consuming component will need to change as well:

export default component$(() => {
  const products = useProductsLoader();

  return (
    <div>
      <div>{products.value.url.href}</div>
      <ul>
        {products.value.products.map((product) => {
          return (
            <li>
              <div>{product.name}</div>
              <div>{product.description}</div>
            </li>
          );
        })}
      </ul>
    </div>
  );
});
Enter fullscreen mode Exit fullscreen mode

As you can see, the change is how I consume the returned value of the url and the products.

Conclusion

Qwik and QwikCity are evolving and adding new features, which are very useful for developer experience with the frameworks. One of these new features is the data loader. In this post I covered what is a data loader and how to use it.

If you have any questions about the subject, write them in the comments section.

Top comments (0)