There are many ways to extract data in Vue, so today, we'll look at 5 ways you can fetch data in your application. We will also look at the new Vue 3 suspense API which tackles this problem differently and create our own composable function to maximize reusability.
April 26, 2021
5 Ways to Fetch Data from an API in Vue 3 Composition APIWhere to fetch data?Fetch APIAxiosAsync awaitSuspenseComposition HookuseAxiosuseFetchConclusion
Vue is a wonderful tool for building rich and highly scalable user interfaces. One of its awesome features is its ability to fetch data from other resources and create beautiful interactive websites.
When building applications you want to request data from your own or a third-party API. There are many ways to extract data in Vue, so today, we'll look at 5 ways you can fetch data in your application.
Before we can do that, we must determine where to do the data fetching. The questions really depend on the application. Like who is interested in the data? Where do you want to display status updates? and where should the optional error message be displayed?
In general, it is usually a common parent who will do the job. It will fetch the data, store it in its local state and distribute it to the children.
However, if you stick around until the end we will take a look at the new Vue 3 suspense API which tackles this problem differently and create our own composable function to maximize reusability.
We can call the
fetch() method providing a URL, and then convert the result to a JSON object. We can take this result and assign it to a ref so we can access it in our template.
While the fetch method is simple and really straight forward we could instead use a library like Axios. Axios is similar to fetch, but it has some nice features. Most noticeably, it returns the result as a JSON object, so we don't need to convert it.
To use it, we'll need to install it using yarn or any other package manager. Then we can import it to our project and we use it in the same way we used to fetch.
What's convenient about using Axios is that it has a much shorter syntax allowing us to cut down on our code and also includes a lot of features that Fetch does not have in its API.
In ES7, it became possible to resolve promises using the async-await syntax. If you are not familiar with such a function. The benefit of this is that it enables us to remove our
.then() callbacks and simply get back our asynchronously resolved data
There are actually two ways we could use this syntax in our component.
The first is we can use an async callback in the
onMounted lifecycle hook and assign our values to refers accordingly.
However in Vue 3 we also have the options of making out setup function async, and instead, call our function at the root of our component.
What's great about async components is they are suspensible by default.
This means if it has a
<Suspense> in the parent chain. If we wrap the above component in Suspense it will display fallback content until the async operation in our component is resolved.
We can combine this with the
onErrorCapture lifecycle hook to catch errors. This way we can display a proper error message.
Suspense is a very handy component that enables an easy and elegant way of displaying fallback content until async operations are performed.
The last way is we could use composable functions, you could do this with external libraries.
A popular example is the
useAxios hook in Vue use. This function wraps around the axios api and provides some reactive states such as error, loading, and response, out of the box.
For GraphQL users we can use Vue Apollo which provides functions for querying, mutating, and subscribing.
However, using these libraries isn't necessary as we could easily create our own query hook that even provides caching.
We'll start by creating a useFetch function that will accept 2 arguments.
We'll create our own async fetch function where we will call axios and pass it to the config object. We'll store these results and data in a ref. In the catch statement will store the error in a ref as well. On top of this, we can add a loading indicator to let us know what the status of the request is.
Now, all we need to do is call our fetch function and return all these properties from the function so we can access them in our component.
I'll also add a config skip check to give us the options to skip fetching the data if we would like to do so manually.
Sometimes you may request data from a resource multiple times. If a user navigates away from the page and then comes back, it would be nice to already have the information saved from the previous request. So let's extend upon our useFetch function by adding cache.
We'll create a new function called useFetchCache, this function will cache 3 arguments, the key which will use for the cache as well as the URL and config.
We'll also need to initialize a map to store our cache results. This map will be reactive so that if you call this function multiple times with the same key, the will update if the value changes.
We can call our previous function from before, except we will want to make sure we enable the skip option since we will only want to fetch data if it's not in our cache.
I'll also create some simple helper functions for updating and clearing the cache using our key.
We'll create a new fetch function that will wrap around the old one. We'll do this so we can update or clear our cache if the request is successful.
Next, we'll need to define new response and data refs since we just want them to use the cache map values. Since the cache map is reactive anytime the value is updated in the map, these computed properties will be updated to reflect that.
We can use our response to make sure we only call the fetch function if there isn't already a response.
Let's return all these values so we can access them in our components.
There are also many other ways to fetch data, but these are the most common.
If you made it this fair don't forget to like this video. I also have a growing community over on discord, if you have any questions.
Become a member and gain access to premium content.