Angular2 – Making Http Requests

Introduction

  • Traditional Web apps against SPAs

Example App & Backend setup

  • We use firebase to make a test database: https://ng-http-cb90d.firebaseio.com/
  • NOTE: Keep in mind set database rules to get free access:
{
  "rules": {
    ".read": "true",
    ".write": "true"
  }
}

 

Sending requests (example POST)

  • With the Angular Http class we can create Observables.
  • But the request is not sent until someone subscribe to that observable.
  • In the next example, we click on a button to subscribe to the POST method which trigger the POST request.

server.service.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

@Injectable()
export class ServerService {
  constructor(private http: Http) {}

  storeServers(servers: any[]) {
    return this.http.post('https://ng-http-cb90d.firebaseio.com/data.json', servers);
  }
}

app.module.ts

providers: [ServerService],

app.component.ts

  constructor(private serverService: ServerService) {}
  
  onSave() {
    this.serverService.storeServers(this.servers). subscribe (
      (response)=> {
        console.log(response);
      },
      (error) => console.log(error)

    );
  }

app.component.html

      <button type="button" class="btn btn-primary" (click)="onSave()">Save servers</button>

Adjusting request headers

  • We can add headers with the Headers class:

server.service.ts

  storeServers(servers: any[]) {

    const headers = new Headers({'Content-type': 'application/json'});
    return this.http.post('https://ng-http-cb90d.firebaseio.com/data.json', servers, { headers: headers });
  }

Sending GET requests

app.component.ts

  onGet() {
    this.serverService.getServers().subscribe(
      (response: Response) => {
        const data = response.json();
        console.log(data);
      },
      (error) => console.log(error)
    );
  }

server.service.ts

  getServers() {
    return this.http.get('https://ng-http-cb90d.firebaseio.com/data.json');
  }

 

Sending a PUT requests

  • In Firebase the POST methods add items to the database, but with the PUT method we can update the whole database. (This is depending of the backend database)
  storeServers(servers: any[]) {
    const headers = new Headers({'Content-type': 'application/json'});
    return this.http.put('https://ng-http-cb90d.firebaseio.com/data.json', servers, { headers: headers });
    // return this.http.post('https://ng-http-cb90d.firebaseio.com/data.json', servers, { headers: headers });
  }

Transform response easily with observable operators (map())

  • Lets extract the data from the server response to render it properly.
  • We can use map() (import rxjs/Rx is needed) for transform response from the server. What map method does is transform an observable in another observable.
  • We will make this transformation in the service which is much better (a centralized place):
  getServers() {
    return this.http.get('https://ng-http-cb90d.firebaseio.com/data.json')
    .map(
      (response: Response)=> {
        const data = response.json();
        return data;
      }
    );
  }

Using the returned data

server.service.ts

getServers() {
    return this.http.get('https://ng-http-cb90d.firebaseio.com/data.json')
    .map(
      (response: Response)=> {
        const data = response.json();
        for(let server of data) {
          server.name = 'FETCHED_' + server.name;
        }
        return data;
      }
    );
  }

app.component.ts

    this.serverService.getServers().subscribe(
      (servers: any[]) => {
        // const data = response.json();
        console.log(servers);
        this.servers = servers;
      },
      (error) => console.log(error)
    );

 

Catching Http errors

  • We want to catch request errors and print more friendly messages to the chrome console.
  • We force and error removing .json at the end of the url.

server.service.ts

  return this.http.get('https://ng-http-cb90d.firebaseio.com/data')
...
    .catch(
      (error: Response) => {
        console.log(error);
        return Observable.throw('Something went wrong');
        // return Observable.throw(error);

      }
    );

app.component.ts

  onGet() {
    this.serverService.getServers().subscribe(
      (servers: any[]) => {
        // const data = response.json();
        console.log(servers);
        this.servers = servers;
      },
      (error) => console.log(error)
    );
  }

Using the async pipe with Http requests

  • We explain here how to use async to render values depending of http requests.

server.service.ts

  getAppName() {
    return this.http.get('https://ng-http-cb90d.firebaseio.com/appName.json')
    .map(
      (response: Response) => {
        return response.json();
      }
    );

  }

app.component.ts

appName = this.serverService.getAppName();

app.component.html

<h1>{{appName | async}}</h1>