Angular 4 — Third Party API’s

Frederick John
Jul 19, 2017 · 9 min read
Angular Logo, courtesy of Angular Team

Angular 4, henceforth known as just “Angular”, is a robust framework for developing responsive web applications. Angular is a great framework but it’s a lot to learn. It’s common for beginners to feel a certain sense of difficulty when they first approach the framework. Often times this is enough for developers to shy away, opting for something they are already familiar with. It’s true that Angular is not easy to learn. It is a comprehensive framework that ensures applications are scaleable, extensible, and maintainable. It produces modular projects that adhere to the best practices of good design. Angular is more difficult but equally more awesome than any other framework. Taking the time to learn Angular is well worth it as it’s an investment that pays off exponentially.

One of the first tasks developers need to learn is how to gather data from the web. Angular has a certain procedure for accomplishing this, a best practice. It may seem like more writing but ultimately produces higher quality code that is easier to test, debug, and maintain. We can break this process up into smaller steps so it’s easier to understand.

Step One (Optional)

Where are you keeping sensitive data?

Step one is optional yet highly recommended. There are several ways to protect private information. The simple, preferred method is to enter the information in the environment.ts file, located in the app/environments folder. If you’re using the Angular CLI (you should be), Angular has already created a const object called ‘environment’ . Simply add ‘name:value’ pairs to this object, where you refer to the ‘name’ of the secret ‘value’. Here we’ll store the url for an api and any keys or additional data. For example, we can add an api url that we can refer back to later.

export const environment = {
production: false
api_url: 'http://jsonplaceholder.typicode.com/posts/'
};

Don’t forget to add app/environments/environment.ts to the .gitignore file so you don’t check it into source code by mistake!

Step Two (Optional)

How are you modeling your data?

Step two is optional yet highly recommended. Applications deal with data. The data may be images, posts, tweets, or anything else. Before you begin working with data, whether in a RESTful way or not, you should create a model. A model is a great way to shape and define data. Also, models provide a schema for later saving their instances to a database. The preferred way to create a model in Angular is by using a Typescript interface. An interface is an outline of how the data should look. For example, if we are defining a “Post” interface it may look something like this.

export interface Post {
userId: number;
id: number;
title: string;
body: string
}

To make the file easily accessible we can put it in the “app” folder.

Step Three

Creating our components

We need to create components to handle our data. How many components we need and how they are related depends on factors that are unique to each application. For this example, we’ll create two components, a parent and child. Using the Angular CLI, we can take advantage of the aliasing provided: “g” for generate and “c” for component. The commands become, ng g c post and ng g c post-list. Now we have two components for handling our data. We could use the Angular’s Http module to fetch placeholder data from our component, however, this violates the Single Responsibility Principle (SRP). Instead, we will follow the best practices of Angular’s Style Guide and fetch data through a service.

Step Four

Creating a Service to fetch data

We will return to the Angular CLI once again to create a service. The alias for service, “s”, can be used to create the service: ng g s post. This creates a “post.service.ts” file and adds the “PostService” import to the app.module.ts. It also produces a warning that the service has been created but no provider has been specified. This warning reminds us that in order to use our service we need to add “PostService” to the “providers” array in app.module.ts. Thank you for the reminder Angular!

// app.module.ts
...
// rest of the file snipped for brevity

providers: [PostService], // added PostService to providers array
bootstrap: [AppComponent]
})
export class AppModule { }

Before we begin working on our service, lets create an rxjs-operators.ts file to import the Reactive Extensions operators we plan on using. In this file we’ll start by importing 3 operators:

// rxjs-operators.tsimport 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';

Now we only need to import one line in our post.service.ts file to gain access to all three operators, rather nifty.

// post.service.tsimport { Http, Response } from '@angular/http';
import { Injectable } from '@angular/core';
import {Post} from './post';
import { Observable } from 'rxjs/Observable';
import './rxjs-operators';
import { environment } from './../environments/environment';
@Injectable()export class PostService {}

Notice that the PostService is decorated with the “@Injectable” decorator and we’ve imported the Http as well as the Response modules from ‘@angular/http’. We imported our environment file that we set in step one, we’ll be using that soon. We’ve also imported “Observable” from ‘rxjs/Observable’. Angular’s Http module now uses observables by default, which means when we use the GET method we will receive an observable as a response. If you aren’t familiar with observables you’ll need to start catching up. They are native in Angular and soon to be native in ECMAScript. They provide methods for composing asynchronous streams of data that can be subscribed to, combined, manipulated, and more. Consider reading this Github gist.

Our PostService will gather data for us over the web and so the constructor should create an instance of the Http module.

constructor(private http: Http) { }

We’ll create a “getData” method that sends a GET request to the server and handles the response.

getData(): Observable<Post[]> {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
}

The first line defines the function getData() of type “Post”. Recall that we created a post interface earlier and we’ve imported “Post” near the top of the file. We return this.http.get(‘url to get data’). The service is returning the response for us to work with in our component. The “http” is an instance of Http and “get” is one of the methods of Http. Next, we use the .map operator and pass in a function “extractData”. Passing a function to map is optional. In doing so, the getData() function is shorter and easier to test and read. We could just as easily passed the contents of extractData() to the map operator,

private extractData(res: Response) {
let body = res.json();
return body || [];
}

The response instance exposes a json method which converts the returned serialized payload string into its corresponding in-memory object representation. With the extractData() function, we are either returning the body, which is the serialized json or an empty array. Our getData() function also uses the .catch operator to handle errors, passing in the handleError() function:

private handleError(error: any) {
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg);
return Observable.throw(errMsg);
}

We now have a PostService that fetches our data and provides methods for handling responses and errors. The entire post service should look like this:

// post.service.tsimport { Injectable } from '@angular/core';
import {Post} from './post';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import './rxjs-operators';
import { environment } from './../environments/environment';
@Injectable()export class PostService {

private url = environment.api_url; // STEP ONE
constructor(private http: Http) {} getData(): Observable<Post[]> {
return this.http.get(url)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || [];
}
private handleError(error: any) {
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}

Step Five

Using the PostService

We’ve created the PostService for gather data, now let’s use it. In the post-list.component.ts, we will start by importing the necessary files.

import { Component, OnInit } from '@angular/core';
import { PostService } from '../post.service';
import { Post } from '../Post';

We import the “OnInit” lifecycle hook, our “Post” interface, and our “PostService”. The OnInit hook can be used to run any initialization code for our component. This allows us to remove initialization code out of our constructor. The constructor should be kept as brief as possible to reduce dependencies and make testing easier.

export class PostListComponent implements OnInit {private posts: Post[] = [];
private errorMessage: any = '';
constructor(private postService: PostService) {
}

Notice that we also created two properties on our PostListComponent, we defined a “posts” property of type “Post” and an “errorMessage” property of any type. Then we inject our PostService into the constructor by creating a “postService” instance. At this point, we have a PostService that will fetch our data and we have injected that service into our component. All that remains is to “subscribe” to the observable so we can retrieve the serialized json data and display it in our view. We define a getPosts()method:

getPosts() {
this.postService.getData()
.subscribe(
posts => this.posts = posts,
error => this.errorMessage = <any>error);
}

The getPosts() method uses the instance postService to call “getData”. Recall that “getData” is defined in our post.service.ts file and uses http.get(‘URL’) to fetch data from the server. We then subscribe to the observable and define our posts and error properties.

Step Six

Calling PostService during the component’s initialization

When the page is loaded we want the service to fetch the data right away. To accomplish this we use the OnInit lifecycle hook and call getPosts. The PostListComponent in its entirety then becomes:

// post-list.component.ts
import { Component, OnInit } from '@angular/core';
import { PostService } from '../post.service';
import { Post } from '../Post';
@Component({
selector: 'app-post-list',
template: `
<div>
<ul class="items">
<li *ngFor="let post of posts">
<span>{{post.title}}</span>
</li>
</ul>
</div>
`,
styleUrls: ['./post-list.component.scss']
})
export class PostListComponent implements OnInit { private posts: Post[] = [];
private errorMessage: any = '';
constructor(private postService: PostService) {} ngOnInit() {
this.getPosts();
}
getPosts() {
this.postService.getData()
.subscribe(
posts => this.posts = posts,
error => this.errorMessage = <any>error);
}
}

In the template, we use the “*ngFor” directive to loop through the posts and print out their titles by interpolating their “title” property. Remember that the posts are of type “Post”, where we have defined a “title” property. Lastly, the selector “app-post-list” will need to be added to the “app.component.html” page.

// app.component.html<h1> Post Titles </h1><app-post></app-post>

From the command line run ng s -o to serve the application using the development server on port 4200. The -o option will open the app in your default web browser. Once the application loads you should see a list of posts on the page:

List of post titles from json.placeholder

If you are using the Chrome browser there is an extension called “Augury”, which is useful for working with Angular applications. Download Augury from the chrome store. Right click on the page and inspect any element to bring up the development tools in chrome, the Augury tab will be on the far right. You may need to close and reopen your browser to see the tab.

Screenshot of the Augury tab

Notice how Augury shows the component tree on the left side. By clicking on PostListComponent we can see the current state. We have a posts object, which is an array of 100 posts with “userId”, “id”, “title”, and “body” properties. Augury can be very useful if you are receiving data from an API and you are unsure of how the data is structured. For example, we now know that we can display the body of the post by {{ post.body }}. You’ll find the app’s repo at github. Feel free to play around and try accessing different parts of the response. As a suggestion, try displaying just the first ten post titles. Or, access the first three post titles with their respective bodies.

I hope you’ve enjoyed this article and got something out of it. For free courses on Angular and other technology stacks visit Learn2Code. My book on Angular will be coming out soon on Gitbook (it’s free).

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade