Making HTTP Requests
sending requests (Example: POST request)
create a class to act as local service wrapping the built-in Angular Http type
decorate class with Injectable as Angular's Http service will be injected into the type
add a method to post servers to Firebase
Http uses Observables under the hood so method should return an Observable because the Http's post method creates an Observable
data.json tells firebase the request is to work with its database
    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://udemy-ng-http-169ea.firebaseio.com/data.json', servers);
        }
    }  
        
in app.module import the service and set it as a provider
    ...
    import { ServerService } from './server.service';

    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        ...
      ],
      providers: [ServerService],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
        
in the component markup add a button to save the servers with a click handler
    <button class="btn btn-primary" (click)="onSave()">Save Servers</button>
        
inject the service into the component
in the handler subscribe to the Observable returned by the service method
the post method is invoked when the Observable is subscribed to
there is no need to unsubscribe because the subscription only makes a single request
    ...
    import { ServerService } from './server.service';
    ...
    export class AppComponent {
      servers = [...];

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

Top

Index

adjusting request headers
the Headers c'tor takes a JSON object as an arg
a third arg can be included with post invocation
the arg is a JSON object which as shown below includes the JSON header object
    import { Injectable } from '@angular/core';
    import { Headers, Http } from '@angular/http';

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

        storeServers(servers: any[]) {
            const headers = new Headers({'Content-Type': 'application/json'});
            return this.http.post('https://udemy-ng-http-169ea.firebaseio.com/data.json', servers, {headers: headers});
        }
    } 
        

Top

Index

sending GET requests
in server.service add a method named getServers
the method returns an Observable
    import { Injectable } from '@angular/core';
    import { Headers, Http } from '@angular/http';

    @Injectable()
    export class ServerService {
        constructor(private http: Http) { }
        ...
        getServers() {
            return this.http.get('https://udemy-ng-http-169ea.firebaseio.com/data.json');
        }
    } 
        
in the component markup add a button with an onGet event handler
    <button class="btn btn-primary" (click)="onSave()">Save Servers</button>
    <button class="btn btn-primary" (click)="onGet()">Get Servers</button>
        
in the component add the event handler
the response includes a stringified JSON object
the response's json method unstringifies the data into an object
    ...
    export class AppComponent {
      ...
      onGet() {
        this.serverService.getServers().subscribe(
          (response: Response) => {
            const data = response.json();
            console.log(data);
          },
          (error) => console.log(error)
        );
      }
      ...
    }   
        

Top

Index

sending a PUT request
in server.service comment the line using the post method and replace it with a similar line using the put method
post appends data while put overwrites the existing data (Firebase)
    ...
    @Injectable()
    export class ServerService {
        constructor(private http: Http) { }

        storeServers(servers: any[]) {
            const headers = new Headers({'Content-Type': 'application/json'});
            // return this.http.post('https://udemy-ng-http-169ea.firebaseio.com/data.json', servers, {headers: headers});
            return this.http.put('https://udemy-ng-http-169ea.firebaseio.com/data.json', servers, {headers: headers});
        }
        ...
    }
        

Top

Index

transform responses easily with Observable operators (map())
in the server.service use the Observable's map method to create a new Observable containing the data a JSON object
no need for callers to reinvent the wheel
    import { Injectable } from '@angular/core';
    import { Headers, Http, Response } from '@angular/http';
    import 'rxjs/Rx';

    @Injectable()
    export class ServerService {
        constructor(private http: Http) { }
        ...
        getServers() {
            // map used to build new observable containing data
            return this.http.get('https://udemy-ng-http-169ea.firebaseio.com/data.json').map(
                (response: Response) => {
                    const data = response.json();
                    return data;
                }
            );
        }
    }
        
in the component change the onGet method to receive an array of servers instead of a Response object
    ...
    export class AppComponent {
      ...
      onGet() {
        this.serverService.getServers().subscribe(
          (servers: any[]) => {
            console.log(servers);
          },
          (error) => console.log(error)
        );
      }
      ...
    }
        

Top

Index

catching HTTP errors
in server.service append the catch method in getServers to the http.get method
the error will be logged both here and in app.component
    import { Injectable } from '@angular/core';
    import { Headers, Http, Response } from '@angular/http';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/Rx';

    @Injectable()
    export class ServerService {
        constructor(private http: Http) { }
        ...
        getServers() {
            //return this.http.get('https://udemy-ng-http-169ea.firebaseio.com/data.json').map(
            return this.http.get('https://udemy-ng-http-169ea.firebaseio.com/data').map(
                ...
            ).catch(
                (error: Response) => {
                    console.log(error);
                    return Observable.throw('error message');
                }
            );
        }
    }
        

Top

Index

using the "async" pipe with HTTP requests
add a kvp to the Firebase database { 'appName': 'http' }
in server.service add a method named getAppName which queries for the kvp
     ...
    export class ServerService {
        constructor(private http: Http) { }
        ...
        getAppName() {
            return this.http.get('https://udemy-ng-http-169ea.firebaseio.com/data/appName.json')
                .map(
                    (response: Response) => {
                        return response.json();
                }
            );
        }
    }
        
in the component add an appName property which is assigned by the new service method
    ...
    export class AppComponent {
      appName = this.serverService.getAppName();
      servers = [...];

      constructor(private serverService: ServerService) { }
      ...
    }
        
in the component markup add a header which uses string interpolation and the async pipe
    <h3>{{ appName | async }}</h3>
        

Top

Index

n4jvp.com