In my previous article, I showed you how to use Cordova plugins inside an Ionic 2 application. Now it’s time to discuss another topic I briefly covered in another article named: Ionic 2 | Tutorial | Let’s create our first application; we’re going to talk about making REST HTTP calls with Ionic 2.
 
This may not surprise you, but making HTTP requests in Angular2 looks a lot different compared to Angular1. The biggest difference being that Angular2 HTTP requests now return observables.
 
I should also state that Angular2 HTTP implementation is still a work in progress. I will update this article if anything changes in a meantime.
 
This article will show you how to make an HTTP REST call and how to handle the final response.
 
 

Note: If this tutorial was helpful, need further clarification, something is not working or do you have a request for another Ionic post? Furthermore, if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here, again leave me a comment below. I'm here to help you, I expect the same from you. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com, or follow and mention me on twitter (@gajotres). Thanks and have a nice day!

PS. If you want my help, if possible (even if it takes you some time to do that), create a working example I can play with. Use Plunker for AngularJS based questions or jsFiddle for jQuery/jQuery Mobile based questions.


 

Table of Contents

 
Ionic 2 is causing you problems? Are you struggling to make it work? Trust me, I wasn’t in any better situation. If you require more information beyond the subject of this article you will probably find it in a list below. Take a look; if there’s a topic not covered there, leave me a comment and I’ll cover it.
 
 

Preparations

 
Before we can begin, make sure you have everything preconfigured for Ionic 2.
 
You should have these:
 
  • Android Environment (or iOS if you’re working on a MacOS)
  • nodeJS
  • Ionic 2
  • Cordova
 
Find more information here: IONIC 2 | INSTALLATION GUIDE if you don’t have a previous Ionic 2 installation or if you have never read my previous articles on this topic.
 

1. Update Ionic & Cordova

 
You need to have a latest nodeJS version, without it, you’ll not be able to install/update Cordova and Ionic appropriately.
 
If you have a previous Ionic/Cordova installation make sure its up to date, older versions may not work with this tutorial. Though latest versions may also mess things up:
 
npm install -g cordova ionic@beta
 
or you can even do it with this:
 
npm update -g cordova ionic@beta
 
I will remove beta keyword once Ionic 2 reach RC status.
 
Warning: Ionic2 is still in beta status so the final implementation may differ from this code. I will update this article if and when that happens.
 
 
 

2. Create A New Project

 
ionic start Ionic2RESTHttpExample blank --v2
cd Ionic2RESTHttpExample
 
Open app directory and remove all content from a directory called pages but don’t delete it. Somewhere below you’ll find a link to GitHub repo holding a working example (or you can copy past provided code). Download zipped project repo folder, copy app and www directory and past it into a newly created folder.
 
Warning: Since some of you never worked with Ionic CLI. From this point and further, every time I tell you to execute something, do that inside a project folder.
 

3. Install Cordova Whitelist plugin

 
If you’re using Cordova 4+ and especially if you’re accessing remote content don’t forget to install Cordova Whitelist plugin:
 
cordova plugin add cordova-plugin-whitelist
 
Open www folder and add this security meta tag to index.html file:
 
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval' 'unsafe-inline' *; object-src 'self'; style-src 'self' 'unsafe-inline'; media-src *">
 

4. Add Required Platform

 
Add Android platform:
 
ionic platform add android
 
MacOS users can also add iOS platform:
 
ionic platform add ios
 

Embeded example:

 
Ionic Page Navigation
 

Making REST HTTP calls

 
Here’s a component we’re going to use to make a REST call:
 
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
 
export class MovieService {  
    static get parameters() {
        return [[Http]];
    }
 
    constructor(private http:Http) {
		
    }
 
    searchMovies(movieName) {
        var url = 'http://api.themoviedb.org/3/search/movie?query=&query=' + encodeURI(movieName) + '&api_key=5fbddf6b517048e25bc3ac1bbeafb919';
        var response = this.http.get(url).map(res => res.json());
        return response;
    }
}
 
As you can see, this is just a simple class without a visible view component.
 
The First thing we need to do is import necessary components:
 
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
 
  • Http is service that provides a fairly straightforward way of handling requests. Just remember Angular1 $http but with one major difference. HTTP calls in Angular2 will return observables where Angular1 request will return promises.
  • RxJs in rxjs/add/operator/* stands for Reactive Extensions for JavaScript. It’s a set of libraries which enables us to compose asynchronous/event-based programs using observable collections. And if we want to be more specific about a map operator used here, it’s used, so to speak, to transform a collection of items into a collection of different items.
Now we need to inject Http service into MovieService class constructor:
 
    static get parameters() {
        return [[Http]];
    }
 
    constructor(private http:Http) {
		
    }	
 
And finally, this is how we can parse HTTP response to a more readable format:
 
var url = 'http://api.themoviedb.org/3/search/movie?query=&query=' + encodeURI(movieName) + '&api_key=5fbddf6b517048e25bc3ac1bbeafb919';
var response = this.http.get(url).map(res => res.json());
return response;
 
If you need to make a POST request just replace a get function with a post, like this:
 
var response = this.http.post(url).map(res => res.json());
 

Source Code

 
Update: 28.06.2016 (June 28th) - Article and example are updated to match changes made to Ionic 2.0.0-beta.10 version
 
In case GitHub repo is not available, and you can only use code provided below, this is what project folder looks like (image was taken from the Sublime text editor):
 
Ionic 2 First App Folder Structure
 
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <title>Ionic</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval' 'unsafe-inline' *; object-src 'self'; style-src 'self' 'unsafe-inline'; media-src *">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">

  <link ios-href="build/css/app.ios.css" rel="stylesheet">
  <link md-href="build/css/app.md.css" rel="stylesheet">
  <link wp-href="build/css/app.wp.css" rel="stylesheet">
</head>

<body>
  <ion-app></ion-app>

  <!-- cordova.js required for cordova apps -->
  <script src="cordova.js"></script>
  <!-- Polyfill needed for platforms without Promise and Collection support -->
  <script src="build/js/es6-shim.min.js"></script>
  <!-- Zone.js and Reflect-metadata  -->
  <script src="build/js/Reflect.js"></script>
  <script src="build/js/zone.js"></script>
  <!-- the bundle which is built from the app's source code -->
  <script src="build/js/app.bundle.js"></script>
</body>

</html>
 
app.html
<ion-nav [root]="rootPage"></ion-nav>
 
app.ts
import {Component} from '@angular/core';
import {Platform, ionicBootstrap} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
import {MovieListPage} from './pages/movie-list/movie-list';


@Component({
  templateUrl: 'build/app.html',
})

export class MyApp {
  rootPage: any = MovieListPage;

  constructor(platform: Platform) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
    });
  }
}

ionicBootstrap(MyApp);
 
app.core.scss
// http://ionicframework.com/docs/v2/theming/


// App Shared Imports
// --------------------------------------------------
// These are the imports which make up the design of this app.
// By default each design mode includes these shared imports.
// App Shared Sass variables belong in app.variables.scss.

@import "../pages/movie-list/movie-list";

@import "../pages/movie-info/movie-info";
 
movie-list.html
<ion-header>
	<ion-navbar>
		<ion-title>
			Movie List
		</ion-title>
	</ion-navbar>
</ion-header>

<ion-content class="home" padding>
	<ion-item>
		<ion-input type="text" placeholder="Search a movie..." (input)="searchMovieDB($event, searchKey)"></ion-input>
	</ion-item>
	
	<ion-list>	
		<ion-item *ngFor="let movie of movies" (click)="itemTapped($event, movie)">
			<ion-avatar item-left>
				<img src="https://image.tmdb.org/t/p/w92{{movie.poster_path}}"/>
			</ion-avatar>
			<h2>{{movie.original_title}}</h2>
			<p class="item-description">{{movie.overview}}</p>
		</ion-item>
	</ion-list>
</ion-content>
 
movie-list.ts
import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {MovieService} from '../services/MovieService';
import {MovieInfo} from '../movie-info/movie-info';

@Component({
    templateUrl: 'build/pages/movie-list/movie-list.html',
    providers: [MovieService]
})

export class MovieListPage {

        movies: Array<any>;

        constructor(private navController: NavController, private movieService: MovieService) {

        }
  
	searchMovieDB(event, key) {
		if(event.target.value.length > 2) {
			this.movieService.searchMovies(event.target.value).subscribe(
				data => {
					this.movies = data.results; 
					console.log(data);
				},
				err => {
					console.log(err);
				},
				() => console.log('Movie Search Complete')
			);
		}
	} 
  
	itemTapped(event, movie) {
		console.log(movie);  
		this.navController.push(MovieInfo, {
			movie: movie
		});
	}
}
 
MovieService.ts
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
 
export class MovieService {  
    static get parameters() {
        return [[Http]];
    }
 
	constructor(private http:Http) {
		
	}
 
    searchMovies(movieName) {
        var url = 'http://api.themoviedb.org/3/search/movie?query=&query=' + encodeURI(movieName) + '&api_key=5fbddf6b517048e25bc3ac1bbeafb919';
        var response = this.http.get(url).map(res => res.json());
		return response;
    }
}
 

Deployment

 
Next step, build our application:
 
ionic build android
 
Be careful here, this step may break if you’re behind a firewall. The first execution will take a long time, so be patient.
 
Finally:
 
ionic run android -l -c -s
 

Download The Code

 
Working GitHub repo link can be found below:
 
GitHub
 
 

What to read next

IONIC 2 | Sharing Data Between Pages/Components
 
 

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.

Blogs worth reading

If you're here looking for information related to the Ionic Framework, you will also like these blogs:






  • Zeak

    Thanks for the tutorial. I’ve been looking for a working example of making a REST API call with Ionic 2. Too many tutorials use one component to do everything. I appreciate you making a REAL example.

    • You’re welcome, if you have more questions just ask, I’m here to help. Plus I always need recomendations for other articles. 🙂

  • Matej

    There is no movie-info in the project

    • My mistake, I was cutting this example to bare minimum. Unfortunately, I forgot to move two references to movie-info page. It’s fixed now,

  • aluknot

    I don’t understand why you are importing “inject”, whay means meta-data in this case? I don’t get the difference between “constructor(@Inject(Http) http: Http)” and “constructor(http: Http)” like i saw in others examples.

    • Paca-vaca

      I think @Inject here is verbose and mostly useless because what it does is injecting a dependency which token cannot be resolved by the type of the argument provided in the constructor function.

  • Jb

    SyntaxError: Ionic2RESTHttpExample/app/app.js: Unexpected token (10:17) while parsing file: Ionic2RESTHttpExampleappapp.js
    any suggestions?

    • Roy Anon

      Because the project is js, but this example is written in ts, it won’t work. Remove the type, and change the import back to js.

    • Roy Anon

      I wonder why it’s so difficult to search how to handle this injection stuff… I don’t know if that’s correct or not.. In all the injection class, put @Injectable(), and make a function with the appropriate type, like static get parameters() {
      return [[IonicApp], [Platform]];
      }

  • Harish Patel

    i am not able to find the movie details page.

  • Leelar Thaophialuang

    Thank you for updating the version to be Typescript now.

    • You’re welcome, I’m also working on my other tutorials

  • Shine Nay Lin Oo

    I encountered the following error in the browser. Any Idea for that?? thanks in advance..!!
    device/simulator
    browser_adapter.js:86 EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in :0:0
    ORIGINAL EXCEPTION: No provider for d3API!
    ORIGINAL STACKTRACE:
    Error: DI Exception
    at NoProviderError.BaseException [as constructor] (http://localhost:8100/build/js/app.bundle.js:1846:23)
    at NoProviderError.AbstractProviderError [as constructor] (http://localhost:8100/build/js/app.bundle.js:27037:16)
    at new NoProviderError (http://localhost:8100/build/js/app.bundle.js:27074:16)
    at ReflectiveInjector_._throwOrNull (http://localhost:8100/build/js/app.bundle.js:28062:19)
    at ReflectiveInjector_._getByKeyDefault (http://localhost:8100/build/js/app.bundle.js:28090:25)
    at ReflectiveInjector_._getByKey (http://localhost:8100/build/js/app.bundle.js:28053:25)
    at ReflectiveInjector_.get (http://localhost:8100/build/js/app.bundle.js:27862:21)
    at ElementInjector.get (http://localhost:8100/build/js/app.bundle.js:29436:48)
    at ElementInjector.get (http://localhost:8100/build/js/app.bundle.js:29436:48)
    at ReflectiveInjector_._getByKeyDefault (http://localhost:8100/build/js/app.bundle.js:28087:24)
    ERROR CONTEXT:
    [object Object]

    • Shine Nay Lin Oo

      here’s my d3API class.. thank you..

  • angatlahi

    thanks for the tutorial. appreciate if you can create also CRUD tutorial using firebase

  • Abhinava Y R

    hi am new to ionic, just a day ago started to learn, here you are created with the existing movie database this example is working fine. now just i wanted to know where to change the database name to connect to database which is i want. and also could you please do send materials to my mail id. so that it can help me a lot..
    thank you soo much.

  • Abhinava Y R

    now i have got one more doubt, in ionic 1.0, application launching from www/index.html rite? in ionic 2.0 it is not starting from www folder instead it is starting from other file why so? how that movie info.ts movie-list.ts and service.ts files created???
    is it required to generate for all application or it is just enough to keep this file for all project?? i just need more information on this .ts files.

  • Leongnidas

    I downloaded your sample code and running “ionic serve –lab” as it is and all three test mobile frames show blanks.
    My version of ionic from using “ionic -v” is 2.1.4 FYI. wonder if there are any changes in-between ionic updates.