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>