VueJS - Reusable Data Fetcher Component
Providing proper feedback to users is essential within a web application context. In this article, I show you how to create a generic VueJS component to manage and display local states throughout your application.
You are probably able to count on the fingers the number of web applications around the world that do not need to fetch remote data and display it to the user.
So, assuming that your next Single Page Application (written using VueJS 😍) will require external data fetching, I would like to introduce you to a component that will help you manage the state of other components that require data fetching and easily provide proper feedback to the users.
First things first
Initially, it is important to think about how rendering the correct state in your application is useful so that users know exactly what is happening. This will prevent them from thinking the interface has frozen while waiting for data to be loaded and also provide them, in case of any errors, with prompt feedback that will help in case they need to contact support.
Loading / Error / Data Pattern
I am not sure if this is an official pattern (please comment below if you know any reference) but what I do know is that this simple pattern helps you to organize the state of your application/component very easily.
Consider this object. It represents the initial state of a users list:
By building state objects like this, you will be able to change the value of each attribute according to what is happening in your application and use them to display different parts at a time. So, while fetching data, you set loading to true and when it has finished, you set loading to false.
Similarly, error and data should also be updated according to the fetching results: if there was any error, you should assign it to the error property, if not, then you should assign the result to the data property.
A state object, as explained above, is still too generic. Let‘s put it into a VueJS application context. We are going to do this by implementing a component and using slots, which will allow us to pass data from our fetcher component to its children.
As per VueJS docs:
VueJS implements a content distribution API inspired by the Web Components spec draft, using the <slot> element to serve as distribution outlets for content.
To start, create a basic component structure and implement the users state object as follows:
Now, create the method responsible for fetching data and update the state object. Notice that we have implemented the API request in the created method so that it is made when the component is fully loaded.
The next step is implementing the template that will display different things according to Loading, Error and Data states using a slot to pass data, when present, to children components.
With the fetcher component built, let´s use it in our UsersList component.
Making the component reusable
That was a very simple approach to implementing the Error / Loading / Data pattern to provide proper feedback to the users when fetching external data, but the implementation above is not very reusable since it is strictly fetching users. By implementing a few changes to our fetcher component, we will make it more generic and we will be able to reuse it for any data fetching we need in our application.
First, let´s make the fetcher component more dynamic since we need to fetch not only users in our application but all kinds of data that require different service methods and variables' names.
In order to do that, we will make use of props to pass dynamic content to the component.
Analyzing each one of the props above:
- apiMethod [required]: the service function responsible for fetching external data
- params [optional]: the parameter sent to the fetch function, if needed. Ex.: when fetching data with filters
- updater [optional]: a function that will transform the fetched result if needed.
- initialValue [optional]: the initial value of the attribute `data` of the state object.
After implementing the required props, let´s now code the main mechanism that will allow the component to be reused. Using the defined props, we are able to set the operations and control the component's state according to fetching results.
So, after implementing these changes, this is how we would use the new Fetcher component.
So, that´s it. Using basic VueJS concepts such as props and slots we were able to create a reusable fetcher component that can be responsible for retrieving data from your API and provide proper feedback to the users of your application.
You can use it more than once on one page and fetch different data as needed.
You can find a fully-working example of this implementation in this repo.
I hope you liked it. Please, comment and share!
Special thanks to Neil Merton for helping me to fix an incorrect piece of code in this article.
Cover image by nordwood.