Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Query A GraphQL API On Android And iOS With NativeScript And Angular

TwitterFacebookRedditLinkedInHacker News

I’ve recently written several tutorials around GraphQL and there are more to come. However, most of these tutorials, including my eBook and video course, Web Services for the JavaScript Developer, have focused on the backend side of things and less of the frontend side of things. Knowing how to create a GraphQL powered API is great, but what if you need to query it from a client facing application?

In a recent tutorial I demonstrated querying a GraphQL API from a Vue.js web application, but what if we wanted to explore something with an Android or iOS mobile application?

In this tutorial we’re going to see how to create an iOS and Android mobile application using NativeScript and Angular and then query a GraphQL API from that application using numerous methods.

The assumption for this tutorial is that you have a GraphQL API available to be accessed. If you don’t and you’d like to get up and running with a basic example quickly, check out my previous tutorial on the subject. In addition to having a GraphQL API, you’ll also need to have NativeScript installed and configured.

What we hope to accomplish can be seen below:

Query GraphQL with NativeScript

As you can see, from a frontend perspective we aren’t exactly doing anything groundbreaking. All the magic comes from the querying of our backend API which is GraphQL powered.

Creating a New NativeScript Project with the Angular Framework

The first step for this tutorial is to create a fresh NativeScript project. NativeScript supports Angular, Vue.js, and its own proprietary format. For this example we’re going to focus on Angular.

From the Telerik NativeScript (TNS) client, execute the following command:

tns create graphql-project --template tns-template-blank-ng

There are other ways to create a NativeScript with Angular project, but the above command will work for us. As of writing this tutorial, I’m using NativeScript 5.1.1 with Angular 7.1.0. I imagine things will change slightly in the future, but you can get a general idea of how things work if they don’t work out of the box with your bleeding edge version of the frameworks.

Querying a GraphQL API with the Angular HttpClient Module

There are several ways to query a GraphQL API from Angular, more than the few that we’re going to see. The first and most basic method to accomplish querying is to use the standard Angular HttpClient module. At the end of the day a GraphQL API is a single endpoint that accepts queries, hence why standard HTTP requests work.

We’re going to start by opening the project’s src/app/app.module.ts file and making the following changes:

import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NativeScriptHttpClientModule } from "nativescript-angular/http-client";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";

@NgModule({
    bootstrap: [
        AppComponent
    ],
    imports: [
        NativeScriptModule,
        NativeScriptHttpClientModule,
        AppRoutingModule
    ],
    declarations: [
        AppComponent
    ],
    schemas: [
        NO_ERRORS_SCHEMA
    ]
})
export class AppModule { }

In the above code you’ll notice that we have imported the HttpClientModule and then added it to the imports array of the @NgModule block. This sets us up for being able to make HTTP requests with the module.

Rather than making a complex application, we’re going to use the components that were created as part of the NativeScript template. Open the project’s src/app/home/home.component.ts file and include the following:

import { Component, OnInit } from "@angular/core";
import { HttpClient } from '@angular/common/http';
import { map, filter, catchError, mergeMap } from 'rxjs/operators';

@Component({
    selector: "Home",
    moduleId: module.id,
    templateUrl: "./home.component.html"
})
export class HomeComponent implements OnInit {

    public people: Array<any>;

    constructor(private http: HttpClient) {
        this.people = [];
    }

    ngOnInit(): void {
        this.http.post("http://10.0.2.2:3000/graphql", {
            query: `
                {
                    people {
                        firstname,
                        lastname
                    }
                }
            `
        }).pipe(map(result => <any>result)).subscribe(result => {
            this.people = result.data.people;
        }, error => {
            console.log(error);
        });
    }
}

I’ve included functional code above using my own GraphQL API. In the ngOnInit lifecycle event, we do a POST request to our GraphQL API. In the above code I’m using the address of my API, so make sure to change it to yours. My API contains people data and a people query. The results can have an id, a firstname, or a lastname property. The query is only asking for two of those properties and the query is executed through the standard HttpClient request.

The result of the request is assigned to the people array which we are going to bind to the XML. Open the project’s src/app/home/home.component.html file and include the following HTML:

<ActionBar class="action-bar">
    <Label class="action-bar-title" text="Home"></Label>
</ActionBar>

<GridLayout class="page">
    <ListView [items]="people" class="list-group">
        <ng-template let-person="item">
            <StackLayout class="list-group-item">
                <Label text="{{ person.firstname }} {{ person.lastname }}"></Label>
            </StackLayout>
        </ng-template>
    </ListView>
</GridLayout>

As you can see in the above HTML, we have a list that iterates our array and renders each item in that array to a row in the list. Nothing complex here and nothing we haven’t already seen before.

Now let’s take a look at an alternative to using the HttpClient module.

Using Apollo to Query the GraphQL API from the NativeScript with Angular Project

When doing a search for GraphQL with Angular, Apollo generally comes up in the results. Apollo has several packages available to make it easier to use GraphQL with various frameworks and programming languages.

To do things the Apollo way, we are going to make a few changes to our project. First we need to install a few Apollo dependencies:

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

With the dependencies downloaded, open the project’s src/app/app.module.ts file and include the following:

import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NativeScriptHttpClientModule } from "nativescript-angular/http-client";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";

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

@NgModule({
    bootstrap: [
        AppComponent
    ],
    imports: [
        NativeScriptModule,
        NativeScriptHttpClientModule,
        AppRoutingModule,
        ApolloModule,
        HttpLinkModule
    ],
    declarations: [
        AppComponent
    ],
    schemas: [
        NO_ERRORS_SCHEMA
    ],
    providers: [Apollo]
})
export class AppModule {
    constructor(apollo: Apollo, httpLink: HttpLink) {
        apollo.create({
            link: httpLink.create({ uri: 'http://10.0.2.2:3000/graphql'}),
            cache: new InMemoryCache()
        });
    }
}

You’ll notice that we didn’t just import the dependencies like we did the HttpClient module. This time around we made use of the AppModule class and its constructor method. In the constructor we linked our API to Apollo for easy access.

Now that Apollo is configured, open the project’s src/app/home/home.component.ts file and include the following TypeScript code:

import { Component, OnInit } from "@angular/core";
import { map, filter, catchError, mergeMap } from 'rxjs/operators';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';

@Component({
    selector: "Home",
    moduleId: module.id,
    templateUrl: "./home.component.html"
})
export class HomeComponent implements OnInit {

    public people: Array<any>;

    constructor(private apollo: Apollo) {
        this.people = [];
    }

    ngOnInit(): void {
        this.apollo.query({query: gql`{people{firstname}}`}).pipe(map(result => <any>result)).subscribe(result => {
            console.log(result.data.people);
        }, error => {
            console.log(error);
        });
    }
}

Notice that this time around we are not using the HttpClient to query our API. This time we are using Apollo and we are only providing the actual query because we had previously configured out API path.

If any of this code looks familiar, some of it was taken from a tutorial by Lukas Marx titled, Learn how to use GraphQL with Angular using Apollo. I wanted to give credit where credit was due even though his tutorial was not directly related to NativeScript and all the code wasn’t copied exactly.

Conclusion

You just saw how to query a GraphQL API from your NativeScript powered Android and iOS mobile application. There are many ways to query a GraphQL API, but we only took a look at two of the more popular methods, one being the HttpClient for Angular and the other being Apollo.

If you want to dive deeper into creating a GraphQL API, I strongly encourage you to check out my eBook and video course titled, Web Services for the JavaScript Developer.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.