How to build a load more button with Vue.js and GraphQL
Tags: vue, graphql, javascript, frontenddevelopment
Published: 2018-04-09 14:52:03

---
title: How to build a load more button with Vue.js and GraphQL
published: true
description: Lazy loading pagination with Graph.cool & Vue.js
tags: Vuejs, GraphQL, javascript, Frontend Development
cover_image: https://thepracticaldev.s3.amazonaws.com/i/toj5y8bxuxh3jogaxkh0.png
---

While I was working on 🎨 [Colour Hunt](https://www.colourhunt.com/?ref=devto) I had to implement pagination at some point. No one wants to load a ton of color palettes at once. However I really like the lazy load approach instead of a classic pagination.

## 💪 Preparation
[Colour Hunt](https://www.colourhunt.com/?ref=devto) is build with Nuxt.js, Graph.cool and [vue-apollo](https://github.com/Akryum/vue-apollo). The stack is a dream for rapid development as you don’t need to fiddle around with a backend. The idea behind Colour Hunt is, that people can create and share color palettes. However you can use this techniques for all kind of graphql nodes. Most examples are using the good old Blog example and posts.

So let’s take a look at our GraphQL query:

![](https://i.imgur.com/LNstiWS.png)

Lets say we have a simple query like this. Just query all palettes that are available and order them by a variable. And our vue component would look like this:

![](https://i.imgur.com/KQa2FFB.png)

We simply load our query, and vue-apollo does all the magic behind the scenes. And we just iterate over our query results. And render the color-palette component.

## 📝 Pagination
We now need to add two arguments to our query. The `skip` argument which defines the *offset* where the query will start and the `first` argument which defines the *limit* or how many element you want to query. And we also need to know how many elements there are. So we utilize the _meta query. So our new query will look like this: 

![](https://i.imgur.com/onGUydf.png)

Now our GraphQL query is ready. And we need to update the Vue component. First we need to update our data. Because we added the `totalCount` to our query.

The `totalCount` is quite important, because we need it to check if there are more palettes to load. If we loaded all palettes, we should not fetch again. We simply add a computed property that will tell us, if we can fetch more. And we can use it, as a condition for our *Load More* button.

![](https://i.imgur.com/LROmQe4.png)

Now we need to update our vue-apollo query and add the missing variables. We should at first create a new variable which holds our number of items we want to fetch. For example `PALETTES_PER_PAGE` which I created as a local const variable. You could also use a separate file like constants.js where you save all this kind of constants. So you can change it in one place.

Now it becomes a bit tricky. Because vue-apollo automatically map your query result to your local data model. But we have two returned objects. First `allPalettes` and second totalCount . I guess you could also execute the query twice, but this seems to me like a code smell. 

Instead we can use the `result()` method which comes with vue-apollo. We simply grab the `totalCount` and assign it to our local `this.totalCount`.

![](https://i.imgur.com/pyKWNrR.png)

Now lets create our button which will fetch more entries. Simple as that we just add a render condition, which is our computed property. 
And as we have our loading state, we can change the button text, depending on if it is loading or not.

And on a click we call our `loadMore()` method, which we will create in a second.

![](https://i.imgur.com/Xe03ukV.png)

## ⚡️ Updating the query
Now comes the fun part. We need to update our query and fetch more. Vue-apollo comes with a build-in method for that. In our `loadMore()` method we just need to call

```js
this.$apollo.queries.allPalettes.fetchMore({
  variables: {
    skip: this.allPalettes.length
  }
})
```

So you remember what the `skip` argument is doing? Right, it is setting an *offset*. In our initial query we set `skip: 0` and `first` to `PALETTES_PER_PAGE` which equals 10. So we are not skipping anything, and loading the first 10 palettes. Now we `fetchMore` and skip the first 10 palettes. Because `this.allPalettes.length` is now 10.

However this is not enough. We also have to update our query in the cache. Which is quite simple: We are checking if there are `fetchMoreResults` if not, we are returning the `previousResults`. Otherwise we append the new palette results to the old one with `Object.assign()` and the spread operator. If you have trouble following, it is always helpful to check out the structure of the apollo cache with the [apollo chrome plugin](https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm)

![](https://i.imgur.com/NJKD4ot.png)

## 🎉 Final Result

And thats actually it! We implemented lazy loading of palettes in just a few lines of code. And here is the final result:

[Shining Gif](https://imgur.com/NrugRHv)

---

I am building [Colour Hunt](https://www.colourhunt.com/?ref=devto) in public and you can follow the progress on [WIP](https://wip.chat/products/880). I am also live streaming the development from time to time.