Angular

Apollo Client For Angular – Making Use of GraphQL


Subscribe On YouTube

DemoCode

The Apollo Client project is part of Apollo and lets you bind GraphQL data to your web user interface. Apollo client is available for major JavaScript frameworks like React, Vue.js, Angular. In this tutorial we’ll take a look at Apollo Client for Angular. We’ll set up a new Angular 5 project from scratch and you’ll learn how to install and make use of Apollo Client to retrieve data from a GraphQL server endpoint and then display those data in your Angular web application.

The Apollo project’s website can be found at https://www.apollographql.com.

Installing Angular CLI and Setting Up An Angular Project

Let’s get started with setting up an Angular project. The easiest way to do so is to use Angular CLI. If Angular CLI is not available on your system yet you first need to follow the instructions on https://cli.angular.io/ to install the Command Line Interface. Once it is installed successfully you can use the ng command to initiate a new project:

$ ng new angular-apollo

Change into the newly created project directory

$ cd angular-apollo

and start up the live-reloading development web server by executing the following command:

$ ng serve

Having started the web server you should be able to see the default application running by accessing URL http://localhost:4200 in the browser.

Installing Apollo Client For Angular

In order to use Apollo Client for Angular we need to add a few packages to our project. Execute the following command within the Angular project directory:

$ npm install apollo-angular apollo-angular-link-http apollo-client apollo-cache-inmemory graphql-tag graphql

The next step is to import two Angular Modules in app.module.ts:

  • ApolloModule: This is the main module to make Apollo Client’s features available in the Angular App
  • HttpLinkModule: Is used to fetch data in Angular

To import both modules you need to add the corresponding import statements to the top of app.module.ts and add both modules to the array which is assigned to the imports properties of the @NgModule decorator.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { ApolloModule } from 'apollo-angular';
import { HttpLinkModule } from 'apollo-angular-link-http';

import { AppComponent } from './app.component';

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

Please note: The HttpLinkModule uses the HttpClient internally. HttpClient is part of HttpClient module, so we need to make sure that this module is imported as well.

Injecting Apollo And HttpLink Service

The next step is to make the Apollo service and the HttpLink service available in our application. In Angular this can be done by using dependency injection. First, add Apollo and HttpLink to the import statements:

import { ApolloModule, Apollo } from 'apollo-angular';
import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http';

Next, inject both services into the constructor of class AppModule:

class AppModule {
  constructor(
    apollo: Apollo,
    httpLink: HttpLink
  ) { }

Now we have an instance of the Apollo service and the HttpLink service available and are able to create a Apollo Client connection to a GraphQL server by using the following code within the constructor:

    apollo.create({
      link: httpLink.create({ uri: '[URL]' }),
      cache: new InMemoryCache()
    });

Here we’re calling the create method of the Apollo object. This method creates a network connection to the GraphQL server and is expecting to get a configuration object as parameter. This objects contains two properties:

  • link: The link to the GraphQL endpoint which should be used. To create a link we’re using the create method of the HttpLink service. The create method is expecting to get a configuration object as a parameter. This object contains the uri property and we need to set the value of the uri property later on to the URL string of the GraphQL endpoint.
  • cache: To enable in-memory caching we need to use the cache property and assign an instance of InMemoryCache here.

In order to be able to use InMemoryCache here we need to add the following import statement:

import { InMemoryCache } from 'apollo-cache-inmemory;

The complete code within app.module.ts should now correspond to the following:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { ApolloModule, Apollo } from 'apollo-angular';
import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    ApolloModule,
    HttpLinkModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor(apollo: Apollo, httpLink: HttpLink) {
    apollo.create({
      link: httpLink.create({uri: '[URL]'}),
      cache: new InMemoryCache()
    });
  }
}

GraphQL Server

In order to be able to pass a GraphQL server endpoint to httpLink.create({uri: '[URL]'}) we need to have a running GraphQL server available. There are different options available:

1) Setting Up Your Own GraphQL Server

The first option is to setup your own GraphQL server from scratch. The easiest way is to use Node.js and Apollo or Node.js and express-graphql like described in our previous post: Creating A GraphQL Server With Node.js And Express

2) Using Apollo Launchpad

The second option is to setup a GraphQL server by using Apollo Launchpad.

Creating a new GraphQL server form scratch is easy by using Apollo Launchpad. The project’s website can be found at https://launchpad.graphql.com.

Launchpad is an in-browser GraphQL server playground. You can write a GraphQL schema example in JavaScript, and instantly create a serverless, publicly-accessible GraphQL endpoint.

Start a new launchpad and insert the following code:

// graphql-tools combines a schema string with resolvers.
import { makeExecutableSchema } from 'graphql-tools';

// Construct a schema, using GraphQL schema language
const typeDefs = `
    type Query {
                allCourses: [Course]
        course(id: Int!): Course
    },
    type Course {
        id: Int
        title: String
        author: String
        description: String
        topic: String
        url: String
    }
`;

var coursesData = [
    {
        id: 1,
        title: 'The Complete Node.js Developer Course',
        author: 'Andrew Mead, Rob Percival',
        description: 'Learn Node.js by building real-world applications with Node, Express, MongoDB, Mocha, and more!',
        topic: 'Node.js',
        url: 'https://codingthesmartway.com/courses/nodejs/'
    },
    {
        id: 2,
        title: 'Node.js, Express & MongoDB Dev to Deployment',
        author: 'Brad Traversy',
        description: 'Learn by example building & deploying real-world Node.js applications from absolute scratch',
        topic: 'Node.js',
        url: 'https://codingthesmartway.com/courses/nodejs-express-mongodb/'
    },
    {
        id: 3,
        title: 'JavaScript: Understanding The Weird Parts',
        author: 'Anthony Alicea',
        description: 'An advanced JavaScript course for everyone! Scope, closures, prototypes, this, build your own framework, and more.',
        topic: 'JavaScript',
        url: 'https://codingthesmartway.com/courses/understand-javascript/'
    }
];

var getCourse = function(root, {id}) { 
    return coursesData.filter(course => {
        return course.id === id;
    })[0];
};

var getAllCourses = function() {
  return coursesData;
}

// Provide resolver functions for your schema fields
const resolvers = {
  Query: {
    allCourses: getAllCourses,
    course: getCourse,
  },
};

// Required: Export the GraphQL.js schema object as "schema"
export const schema = makeExecutableSchema({
  typeDefs,
  resolvers,
});

Or just use the existing launchpad https://launchpad.graphql.com/vm8mjvrnv3 with the endpoint https://vm8mjvrnv3.lp.gql.zone/graphql.

export class AppModule {
  constructor(apollo: Apollo, httpLink: HttpLink) {
    apollo.create({
      link: httpLink.create({uri: 'https://vm8mjvrnv3.lp.gql.zone/graphql'}),
      cache: new InMemoryCache()
    });
  }
}

Requesting Data

Now we’ve successfully set up Apollo Client in our Angular app and established the client connection to the server endpoint. In the next step we’re going to expand the Angular application and include the code which is needed to retrieve data by using GraphQL and then displaying this data to the user.

Therefore we’re adding a new componentsto the project by using Angular CLI once again:

$ ng g c list

With this command we’re adding the following files to our project:

  • src/app/list/list.component.css
  • src/app/list/list.component.html
  • src/app/list/list.component.spec.ts
  • src/app/list/list.component.ts

ListComponent is added to app.modules.ts automatically.

Furthermore add a file src/app/types.ts to the project and insert the following type definition which correspond to the custom object type which has been defined on server-side:

export type Course = {
  id: number;
  title: string;
  author: string;
  description: string;
  topic: string;
  url: string;
}

export type Query = {
    allCourses: Course[];
}

Next, let’s add the code which is needed to retrieve a list of courses from the GraphQL endpoint by using Apollo Client to list.component.ts:

import { Component, OnInit } from '@angular/core';
import { Apollo } from 'apollo-angular';
import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators';

import gql from 'graphql-tag';

import { Course, Query } from '../types';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
  courses: Observable<Course[]>;
  constructor(private apollo: Apollo) { }

  ngOnInit() {
    this.courses = this.apollo.watchQuery<Query>({
      query: gql`
        query allCourses {
          allCourses {
            id
            title
            author
            description
            topic
            url
          }
        }
      `
    })
      .valueChanges
      .pipe(
        map(result => result.data.allCourses)
      );
  }
}

On class level the courses property is defined which is of type Observable<Course[]>. The Observable will contain the data which is returned from the GraphQL server and will later be used in the template code for output.

The Apollo service is injected into the class constructor, so that we can make use of it in method ngOnInit. The query operation is executed by calling apollo.watchQuery. The GraphQL code is assigned to the query property of the object which is passed to that method call. In order to be able to write GraphQL code as a multi-line string we’re using the gql tag which is imported from graphql-tag library.

Adding Bootstrap 4

To make sure that the user interface of our web application is looking good we’re going to use Bootstrap 4 CSS classes in the template code. This required us to add Bootstrap 4 to our project first:

$ npm install bootstrap

After having installed the Bootstrap framework successfully, add the Bootstrap CSS file to the array which is assigned to the styles property in file .angular-cli.json.

      "styles": [
        "../node_modules/bootstrap/dist/css/bootstrap.min.css",
        "styles.css"
      ],

Now we’re ready to make use of Bootstrap’s CSS classes.

Adding A Template for ListComponent

Let’s add the template code which is needed to output the list of courses in file src/app/list/list.component.html:

<div *ngFor="let course of courses | async">
  <div class="card" style="width: 100%; margin-top: 10px">
    <div class="card-body">
      <h5 class="card-title">{{course.title}}</h5>
      <h6 class="card-subtitle mb-2 text-muted">by {{course.author}}</h6>
      <p class="card-text">{{course.description}}</p>
      <a href="{{course.url}}" class="card-link">Go to course ...</a>
    </div>
  </div>
</div>

Here we’re using the courses variable to access the data which has been retrieved from the server. We’re using the ngFor directive here to iterate through the list of courses and generate the corresponding HTML output. Because courses is of type Observable<Course[]> we need to apply the async pipe as well.

Next, we’re include ListComponent in the template code of AppComponent in the following way:

<div class="container">
  <nav class="navbar navbar-dark bg-primary">
    <a class="navbar-brand" href="#">Apollo Client For Angular - Sample Application</a>
  </nav>
  <app-list></app-list>
</div>

Finally, we’re ready to start the server by using Angular CLI again:

$ ng serve

The result in the browser should now look like you can see in the following screenshot:

Summary

Apollo Client makes it easy to access a GraphQL endpoint from within your web application. Apollo Client is available for all major web frameworks. By following the steps of this tutorials you’ve learned how to use Apollo Client within your Angular 5 application.

ONLINE COURSE: Angular - The Complete Guide

Check out the great Angular – The Complete Guide with thousands of students already enrolled:

Angular – The Complete Guide

  • This course covers Angular 5
  • Develop modern, complex, responsive and scalable web applications with Angular
  • Use their gained, deep understanding of the Angular  fundamentals to quickly establish themselves as frontend developers
  • Fully understand the architecture behind an Angular application and how to use it
  • Create single-page applications with on of the most modern JavaScript frameworks out there

Go To Course

ONLINE COURSE: GraphQL with React: The Complete Developers Guide

Check out the great GraphQL with React: The Complete Developers Guide course with thousands of students already enrolled:

GraphQL with React: The Complete Developers Guide

  • Learn and master GraphQL by building real web apps with React and Node
  • Build amazing single page applications with React JS and GraphQL
  • Realize the power of building flexible data schemas
  • Master fundamental concepts behind structuring GraphQL servers
  • Be the engineer who explains how GraphQL works to everyone else, because you know the fundamentals so well

Go To Course


Using and writing about best practices and latest technologies in web design & development is my passion.