You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
Apollo Angular Boost GraphQL Tutorial
Episode 119 written by Arjun YelamanchiliHealth Check: This lesson was last reviewed on and tested with these packages:
- Angular v6
- RxJS v6.2
- Apollo v1.1
Find an issue? Let's fix it
Source code for Apollo Angular Boost GraphQL Tutorial on Github
Welcome to the second half of the Angular Firebase GraphQL tutorial. Make sure to watch the first half about building up a GraphQL server with NodeJS. The second half provides an example of GraphQL queries and optimistic mutations with Apollo Angular Boost.
Initial setup
We start with our Apollo server from part 1, placing the files in the backend folder. Set it up and run the server:
npm run serve |
Generate a new Angular app and install dependencies:
ng new frontend |
Generate the apoll graphql module
ng g module graphql --flat |
Inside the graphql module setup Apollo Boost
import { NgModule } from '@angular/core'; |
Then add our graphQL module to our app.module.ts.
@NgModule({ |
Setup Query
Lets setup our GraphQL query that retrieves all the tweets. In our app.component.ts first we import the tools we need, inject Apollo, and create a new class property holding our tweet query.
import { Apollo, gql } from 'apollo-angular-boost'; |
One of the coolest tools Apollo offers is Apollo Codegen which will generate types for our queries.
cd src/app |
To start out with, we point apollo-codegen at our GraphQL server to generate a schema.json file.
npx apollo-codegen introspect-schema http://localhost:4000/graphql --output ./types/schema.json |
Now that we have our schema we have apollo codegen read the gql tag in our typescript files to see which types we are actually calling.
Codegen is looking for gql
tags in your frontend Angular code, so make sure add them to your component (see prev step) before running this command, otherwise you’ll just get blank types.
npx apollo-codegen generate **/*.ts --schema ./types/schema.json --target typescript --output ./types/operation-result-types.ts |
Using these types lets add a class property, a tweets observable, and call our query on init
export class AppComponent implements OnInit { |
The watchQuery is going to update our observable whenever the underlying Apollo store on our client is updated, even from another query. We’ll see that in the next section when we go over optimistic updates.
In our app.component.html lets output our tweets and a button/likeTweet function we’ll cover in the next section to like a tweet.
<div *ngFor="let tweet of (tweets | async)?.tweets"> |
I used Ionicons for the button, when we use web components make sure to add
schemas: [CUSTOM_ELEMENTS_SCHEMA] |
in our app.module.ts. When you run the app you should now see tweets displayed on the screen!
Setup Mutation
Lets setup a Mutation on our backend that increments the likes on a tweet by 1. Jump into the backend/src/index.ts file and add the mutation to the typeDefs:
const typeDefs = gql` |
Then we code our mutation in the resolver, note that in a real firebase application you would use a transaction to increment the likes. In our example we are just setting the variable, re-fetching it, and returning.
const resolvers = { |
Save and reload the server.
npm run serve |
Let’s return to the app.component.ts and start setting up the likeTweet
method and passing it the gql tag with our type definitions.
likeTweet(id: string, likes: number, text: string) { |
Make sure your terminal is in the src/app folder and re-run the apollo codegen:
npx apollo-codegen introspect-schema http://localhost:4000/graphql --output ./types/schema.json |
This should give you a folder of TypeScript type definitions that we can use to write the mutation function.
likeTweet(id: string, likes: number, text: string) { |
Clicking on the button should now increment the likes. Congrats! You’ve created a GraphQL mutation.
You’ll notice that even though we didn’t tie our query to our tweets observable, it still updated the number with the return from the server. This is because under the hood, Apollo client has its own store where it keeps track of things and one queries result can update another. We can use this to implement optimistic updates.
Optimistic Mutation
Currently when we update the likes it will wait for the server response to update. However for a great user experience we might want to update the UI immediately while the update happens through the network, this is an example of optimistic UI.
We do this by telling Apollo the type, ID, and values of the object we’re going to update. Apollo can update the local store immediately, then when the server response comes it will overwrite it in the store. Change the mutate function:
this.apollo.mutate<likeTweetMutation, likeTweetMutationVariables>({ |
You can use your browser’s dev tools to slow down your internet connection and see that now when you click the button the number changes instantly! Have fun!