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.
- import ‘rxjs/Rx’; 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); }
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:
- Install the the latest beta version of the Ionic CLI:
npm install -g ionic@beta
or
sudo npm install -g ionic@beta
- Clone this repository
- Navigate to the ionic2-realty-rest directory
- Install the dependencies
npm install
- Start the server
node server
- Open another command prompt and type the following command to build the app and start it in the browser:
ionic serve
Pingback: Building Customer-Facing Mobile Apps with Angular 2, Ionic 2, and Salesforce | Christophe Coenraets()