Getting Started With GraphQL in Angular with Apollo

Apollo is a GraphQL client that makes it very easy to develop GraphQL applications with the likes of React and Angular. All you need to get started is a few dependencies and a client configuration, and you’ll be off to the races running queries and mutations against your GraphQL endpoints.

You can refer to our intro to GraphQL queries if you're new to GraphQL in general.

Let’s get started by installing the required packages (apollo-client, apollo-angular and graphql-tag) with Yarn or NPM:

# Yarn
$ yarn add apollo-client apollo-angular graphql-tag

# NPM
$ npm i -S apollo-client apollo-angular graphql-tag
  • apollo-client is the client library that works for any platform.
  • apollo-angular is the Angular integration for the Apollo client.
  • graphql-tag is the tag that parses your GraphQL queries/mutations.

Client Configuration

Let’s create a file called client.ts in the root of our application and include the following:

client.ts

import { ApolloClient, createNetworkInterface } from 'apollo-client';

const clientConfig = new ApolloClient({
  networkInterface: createNetworkInterface({
    uri: 'https://api.graph.cool/simple/v1/abcdefg'
  })
});

export function client(): ApolloClient {
  return clientConfig;
}

Note how we used createNetworkInterface to define our API endpoint. In the example we put a sample Graphcool endpoint. Graphcool is a popular GraphQL backend as a service. The client would default to an endpoint of /graphql if the network interface wasn’t specified.

The Apollo module’s forRoot method takes a function that returns a client configuration, hence our client function in client.ts. In your app module, import the ApolloModule, your client configuration file and add the module to your @NgModule ‘s imports:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { ApolloModule } from 'apollo-angular';
import { client } from './client';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ApolloModule.forRoot(client)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

You’re now ready to start using the client in your components and services.

Using the Client

Let’s see an example of using our newly configured client, here let’s imagine that our GraphQL endpoint on Graphcool has a Post type that can be queried:

app.component.ts

import { Component, OnInit } from '@angular/core';

import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';

@Component({
  ...
})
export class AppComponent implements OnInit {
  loading = true;
  data: any;

  constructor(private apollo: Apollo) {}

  ngOnInit() {
    this.apollo.query({
      query: gql`query getAllPosts {
        posts: allPosts {
          title
          url
        }
      }`
    }).subscribe(({data, loading}) => {
      this.data = data;
      this.loading = loading;
    });
  }
}

We injected Apollo in our constructor and then ran our query in the ngOnInit lifecycle hook.

Notice how Apollo queries return an observable that we can subscribe to, and also how we get loading, which evaluates to true when the query starts and false when it’s resolved. This makes it easy to create loading indicators when getting data from an endpoint.


We could also refactor and have our query strings defined outside of our component class, like this:

import { Component, OnInit } from '@angular/core';

import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';

const allPosts = gql`query getAllPosts {
  posts: allPosts {
    title
    url
  }
}`;

@Component({
  ...
})
export class AppComponent implements OnInit {
  loading = true;
  data: any;

  constructor(private apollo: Apollo) {}

  ngOnInit() {
    this.apollo.query({
      query: allPosts
    }).subscribe(({data, loading}) => {
      this.data = data;
      this.loading = loading;
    });
  }
}

Template Access

And in the template we can access our data with something like the following:

<ul *ngIf="!loading; else loadingMsg">
  <li *ngFor="let post of data.posts">{{ post.title }} - {{ post.url }}</li>
</ul>
<ng-template #loadingMsg>
  Loading your posts...
</ng-template>

We used the else clause that’s available since Angular 4 to show a loading message while our data is being retrieved.

Mutations

Let’s give you an example of how we would create a new post with a mutation when the user clicks a button that’s bound to an newPost method:

newPost() {
  this.apollo.mutate({
    mutation: gql`mutation($title: String, $url: String) {
        createPost(title: $title, url: $url) {
          title
          url
        }
      }
    `,
    variables: {
      title: this.someForm.get('title'),
      url: this.someForm.get('url')'
    }
  }).subscribe(data => {
    console.log('New post created!', data);
  });
}

🌈 That's it for now. Go on and query that graph!

  Tweet It
✖ Clear

🕵 Search Results

🔎 Searching...