Quasar and Apollo - Client State without Vuex - Part 4
Tags: vue, apollo, quasarframework, graphql
Published: 2020-04-05 14:43:53

---
title: Quasar and Apollo - Client State without Vuex - Part 4
published: true
description:  A series of articles to demonstrate Quasar, Vue-Apollo and client state management
tags: Vue, Apollo, QuasarFramework, GraphQL
---

### **Part 4 - The Trick and the Rest of (Vue-)Apollo**

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

If you've landed here inadvertently and haven't read the [**first part**](https://dev.to/quasar/quasar-and-apollo-client-state-without-vuex-2iii), please do. 

**This tutorial has 4 parts:**

* **[Part 1 - Getting Started](https://dev.to/quasar/quasar-and-apollo-client-state-without-vuex-2iii)**
* **[Part 2 - Vue-Apollo and its Working Parts - Queries](https://dev.to/quasar/quasar-and-apollo-client-state-without-vuex-5h8h)** 
* **[Part 3 - Vue-Apollo and its Working Parts - Mutations](https://dev.to/quasar/quasar-and-apollo-client-state-without-vuex-i08)**
**Part 4 - The Trick and the Rest of (Vue-)Apollo *(You are here now)***

In our other three parts, we got you started with a new Quasar project and Vue-Apollo. We also went over how to query for data and to mutate it. Now, we'll explain how it all works....the "trick". 

Have a good look once more at `/graphql/Todos/queries.js`. If you look at all of the queries, there is one directive they all have. 

### >>> *@client*

That is the trick to Apollo's client state management system. You can add the `@client` directive to your queries and, of course, build the query within your local resolvers and instead of pulling the data from your GraphQL server, Apollo pulls the data from its local cache. 

The really cool part about this is, you can mix and match your query's  result fields with `@client` and without it and Apollo will pull only that data from the cache and the rest from the server. We aren't using a server in our todo app, but this is what it might look like (taken from the Apollo docs).

```javascript=
const GET_LAUNCH_DETAILS = gql`
  query LaunchDetails($launchId: ID!) {
    launch(id: $launchId) {
      isInCart @client
      site
      rocket {
        type
      }
    }
  }
`
```

Notice the `@client` directive is only on the `isInCart` field.

To make this happen, this is what your local resolver might look like.

```javascript=
  resolvers: {
    Launch: {
      isInCart: (launch, _args, { cache }) => {
        const { cartItems } = cache.readQuery({ query: GET_CART_ITEMS });
        return cartItems.includes(launch.id);
      },
    },
  },
```

If you'll notice, here only `isInCart` is being givin a true/false value via the `includes` of the `cartItems`. 

The `Launch` object itself (fetched from the server), holds the rest of the needed information for the query to be "fullfilled". This is a key part of why the client state is advantageous over using Vuex. Your request for data, local or otherwise, comes from the same request. It simplifies reasoning about the data you are needing/ requesting a lot. 

### **The `setResolvers` and `addResolvers` methods**

In our todo app, we are defining our resolvers at the time the client is instantiated, by adding them in the constructor function of the client. As our app gets bigger, this might become combursome/ bloaty. If you want your resolvers to be loaded "just-in-time", [**you can use the `setResolvers` and `addResolvers`**](https://www.apollographql.com/docs/react/data/local-state/#code-splitting) methods of Apollo client instead. 

The difference between the two is `setResolvers` will replace all of the resolvers stored in the client and `addResolvers` will overwrite only those with the same name or add any new ones. 

### **Fetching Data, What to Expect and `@client(always: true)`**

If you are regular user of Apollo, you know about [**Apollo's "fetch policies"**](https://). Apollo's fetch policies determine where data should be pulled with a bit of prioritization. If you don't know about them, please read [**this section of the Apollo docs in terms of what to expect with client state**](https://www.apollographql.com/docs/react/data/local-state/#working-with-fetch-policies). 

Bottom line is, you should make sure you are using the local cache, with  the `cache-first` policy. There is, however, a disadvantage to even this policy. If you have local calculations in your resolvers, they won't always be fired on each query. Apollo is smart about this, or is trying to be, so your app does the least amount of work necessary. 

In some instances, however, you might want a calculation made on each request. If you do, there is a solution. The addition of the `always` argument to the `@client` directive. 

It looks like this -> **`@client(always: true)`**. Add this, and your local resolver will always fire with every Query made.

### **So, What's the Big Deal of All This Anyway?**

You might be asking yourself this question and if you haven't noticed the advantages of adding Apollo and GraphQL to your front-end stack, let's discuss it now. 

This is the big key advantage we said we'd cover at the beginning of Part 1. 

### **The Magic of GraphQL**

The heart of GraphQL is the ability to "query" for data and also to "mutate" it. This offers you the following advantages: 

1. You can query data to match only what you need for your components and component hierarchy.
2. You can mutate data within your components at the point of where it actually should be mutated.

The above points offer a better seperation of concerns and responsibility within and among your components. And that, in turn, means clean, easy to reason about and thus, easily fixable and even testable code. 

> ### ***It's high cohesion and low coupling at its best!***

Have a look at this diagram. 

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

This is a simple diagram of our todo app's component hierarchy. As you see, we have the Todos query at the top. This app is simple, but imagine a bigger component with more child components built in. Imagine getting the right data to them, but only for what they exactly need. This is a huge challenge in working with a REST API, but it is the "built-in nature" of GraphQL. Once the query is "formed", fetched and returned, then all that needs to happen is the data be passed down via the component props. With "formed" we mean, the field hierarchy in your query can (and should) match your component hierarchy. 

And, just as your queries perfectly match the component hierarchy, the mutations can be put in the components where data actually needs to be mutated, and completely encoupled from where the data is actually being mutated, as was done in our `TodoToggle` and `TodoEdit` components. 

This affords a very clean, very simple front-end architecture and follows SRP and SoC, thus allowing for a much easier reasoning about your app's state logic. In other words, it simplifies your work as a front-end developer a lot.

### **Conclusion**

Hopefully you enjoyed the articles and got some new perspectives on how a front-end app with Quasar (or Vue) could look using GraphQL, along with not needing Vuex for state management. 

Let us know in the comments below about what you think of GraphQL, Apollo and using them within a Quasar/ Vue app with Vue-Apollo.

Thanks for reading!