In part 1 of this series, I shared two approaches to create Mock services in Angular 2 / Ionic 2 applications: using a Promise-based or an Observable-based API. In this article, I’ll share a version of the IonicRealty sample application implemented using actual REST services, and I’ll revisit the Observable vs Promise discussion.

The code for the application is available in this GitHub repo, including a Node.js server app that powers the REST services.

Let’s take a look at one of the services of the IonicRealty app. PropertyService provides access to the list of Houses and Condominiums for sale, and is implemented as follows (showing only two REST service calls for brevity):

property-service.js:

import {Injectable} from 'angular2/core'; import {SERVER_URL} from './config'; import {Http, Headers, RequestOptions} from 'angular2/http'; import {Observable} from 'rxjs/Observable'; import 'rxjs/Rx'; let favorites = [], propertiesURL = SERVER_URL + '/properties', favoritesURL = propertiesURL + '/favorites'; @Injectable() export class PropertyService { constructor (http:Http) { this.http = http; } findAll() { return this.http.get(propertiesURL) .map(res => res.json()) .catch(this.handleError); } favorite(property) { let body = JSON.stringify(property); let headers = new Headers({ 'Content-Type': 'application/json' }); let options = new RequestOptions({ headers: headers }); return this.http.post(favoritesURL, body, options) .map(res => res.json()) .catch(this.handleError); } handleError(error) { console.error(error); return Observable.throw(error.json().error || 'Server error'); } }

Code highlights:

We use Angular’s http object to access the REST services.

The Angular 2 http object methods (get, post, put, etc.) don’t return Promises: they return Observables from the RxJS library.

The Observable.map() function is used to transform the response in a format easily consumable by the observer.

function is used to transform the response in a format easily consumable by the observer. import ‘rxjs/Rx’; adds all the operators to Observable (map, catch, etc). Operators could also be added individually.

adds all the operators to Observable (map, catch, etc). Operators could also be added individually. When “posting” to the server (like in the favorite function), we need to set the Content-Type header to application/json (the content type expected by our REST service).

Pages and components can then call findAll() and subscribe to process the result as in the ngOnInit function below:

property-list.js:

import {OnInit} from 'angular2/core'; import {Page, NavController, NavParams} from 'ionic/ionic'; import {PropertyDetailsPage} from '../property-details/property-details'; import {PropertyService} from '../../services/property-service'; @Page({ templateUrl: 'build/pages/property-list/property-list.html' }) export class PropertyListPage { constructor(nav:NavController, navParams:NavParams, propertyService:PropertyService) { this.nav = nav; this.propertyService = propertyService; this.selectedItem = navParams.get('item'); } ngOnInit() { this.propertyService.findAll().subscribe( data => this.properties = data ); } itemTapped(event, property) { this.nav.push(PropertyDetailsPage, { property: property }); } }

Promises vs Observables

As discussed in part 1, you could also create your Angular services with a Promise-based API instead of an Observable-based API. To do that, you’d simply use the Observable.toPromise() function to turn Observables into Promises after calling an http object method.

For example, the findAll() function could be rewritten as follows:

property-service.js:

findAll() { return this.http.get(propertiesURL) .toPromise() .then(res => res.json(), err => console.log(err)); }

In PropertyListPage, you could then call findAll() using the traditional Promise syntax:

property-list.js:

ngOnInit() { this.propertyService.findAll().then(data => this.properties = data); }

“Don’t rush to promises until you’ve given observables a chance.”

Keep in mind that Observables are the new standard for the http object in Angular 2 and have advantages over Promises. Check out this video for a quick comparison. To quote the Angular doc:

Deploying and Running on Heroku

The easiest way to deploy and run the application (client and server) is to click Deploy to Heroku button below.

Make sure you are logged in to Heroku (sign up for a free account if you don’t already have one) Click the Deploy to Heroku button below to deploy the application on Heroku





When the deployment process completes, click the View button at the bottom of the screen

Your own instance of the application is automatically deployed.

Deploying and Running Locally

To deploy and run the application (client and server) locally: