Ionic 2 Native

Using Cordova Plugins in Ionic 2 with Ionic Native



·

There’s been a lot of confusion around how to use Cordova plugins in Ionic 2, and I think a lot of that stems from ngCordova. This was a great little tool that simplified using native plugins in Ionic 1, it can not be used with Ionic 2.

What ngCordova did was wrap the standard Cordova plugins to make them integrate better with Angular, and provide things like promise support, whereas vanilla Cordova plugins usually rely on callbacks.

There’s a new service in Ionic 2 called Ionic Native which is pretty much a direct replacement for ngCordova. It’s the exact same idea, it wraps the vanilla Cordova plugins so that they integrate more nicely with Angular 2 by adding things like promise and observable support.

Misconceptions about Ionic and Cordova

Before we talk about Ionic Native, I wanted to clear up a big misconception that I’ve been seeing a lot recently. A lot of people have been asking questions like:

“How do I use Cordova plugins in Ionic 2?”

which is certainly a fair question, but I think it’s coming from a lack of understanding of Cordova itself. To put it simply, Cordova is a project that provides web access to native plugins. It is not anything specific to Ionic, and can be used with any framework that is built with Cordova or even none at all. The way you implement a Cordova plugin with Ionic 2 is the same way you do it with Ionic 1, Sencha Touch, jQuery Mobile, or even just a vanilla Javascript web page you’re building with Cordova. The process is basically this:

1) Install the plugin you want to use by running the appropriate command:

cordova plugin add MY-PLUGIN-NAME

2) Use the plugin by accessing the global object it adds to your application:

window.plugins.myplugin.someMethod()

The way you access the plugins functionality will depend on the plugin that you are using (so make sure to check the documentation) but in general that is pretty much how it’s done (there may be some issues related to TypeScript however, so make sure to check the end of this blog post for a discuss on that).

Where I think a lot of confusion is coming from is that a lot of people’s first experience with Cordova is going to be through using Ionic. If you’re using Ionic then you’re probably also going to be using ngCordova because it makes things so much nicer, and that’s probably what most tutorials will guide you through doing.

But to use ngCordova in Ionic 1 (which I want to stress is optional) you need to do some dependency injection like this:

.controller('MainCtrl', function($scope, $state, $cordovaCamera) {

	var options = {};

    $cordovaCamera.getPicture(options).then(function(imageData) {
        //Do something
    }, function(error) {
        //Do something
    });
});

In the example above we have to inject $cordovaCamera from ngCordova before we can use it, so I think a lot of people assume that you have to inject plugins into your code in some manner when using Ionic 2. But you can just as easily skip ngCordova and dependency injection and just use the plugin directly like this:

.controller('MainCtrl', function($scope, $state) {

    var options = {};

    navigator.camera.getPicture(function(imageData){
        //Do something
    }, function(error){
        //Do something
    }, options);
});

You can do the same thing in Ionic 2 without having to worry about importing anything or setting anything up (aside from installing the plugin) and just using the plugin directly, and up until now this is all you could do.

However, the Ionic team have just recently released Ionic Native which as I mentioned is basically the equivalent of ngCordova for Ionic 2. If you’re using Ionic Native then you will need to import some stuff, and I do recommend that you use Ionic Native, but just keep in mind that it is not a requirement. There are a lot of plugins not covered by Ionic Native which you may want to use the old school way.

Before We Get Started

Now that we’ve covered that bit of theory, let’s get into how to actually use Ionic Native (it’s pretty easy, so this section is probably going to be shorter than the last one!).

Before you go through this tutorial, you should have at least a basic understanding of Ionic 2 concepts. You must also already have Ionic 2 installed on your machine.

If you’re not familiar with Ionic 2 already, I’d recommend reading my Ionic 2 Beginners Guide first to get up and running and understand the basic concepts. If you want a much more detailed guide for learning Ionic 2, then take a look at Building Mobile Apps with Ionic 2.

Using Ionic Native

Let’s start out by generating a new Ionic 2 application to worth with by running the following command:

ionic start ionic2-native-demo blank --v2

and then making it the current working directory:

cd ionic2-native-demo

You will need to install the plugin you want to use. Let’s use the Geolocation plugin as an example:

ionic plugin add cordova-plugin-geolocation

Then you will need to import the plugin into the component that you want to use it in. Let’s add it to the automatically generated home page in home.ts:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { Geolocation } from 'ionic-native';
import { HomePage } from '../pages/home/home';

@Component({
  template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class MyApp {

  rootPage: any = HomePage;

  constructor(platform: Platform) {

    platform.ready().then(() => {

    });
  }
}

and then all that is left to do is use it. Since we’ve imported Geolocation into this class, we can use it in anywhere within the class. Let’s add a bit of code to the constructor (which is the first bit of code to run when page is created) to grab the users current coordinates:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { Geolocation } from 'ionic-native';
import { HomePage } from '../pages/home/home';

@Component({
  template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class MyApp {

  rootPage: any = HomePage;

  constructor(platform: Platform) {

    platform.ready().then(() => {

      Geolocation.getCurrentPosition().then((resp) => {
       console.log("Latitude: ", resp.coords.latitude);
       console.log("Longitude: ", resp.coords.longitude);
      });

    });
  }
}

If you run this project now using:

ionic serve

You will see your current location output to the console:

Screenshot 2016-03-07 21.04.30

An important thing to keep in mind when using native plugins is that most of them will not work through the browser. Geolocation (as well as some others) is a bit of a special case because there is also a browser based HTML5 Geolocation API, so it will work in the browser, but others like the Camera plugin will not.

Using a Plugin Not Included in Ionic Native

There are many plugins supported in Ionic Native already, but you’ll likely run into a situation where the plugin you want isn’t included (and depending on the plugin you want to use, it may never be).

The way in which you use a non Ionic Native plugin in Ionic 2 is the same as the way you would use it in any Cordova project, which is however the plugin’s documentation says you should use it. However, there are some extra steps you need to take because TypeScript will cause some problems.

TypeScript likes to know about everything in your application up front, so much so that it will refuse to even build your application if you try to use something that it doesn’t know about.

Unforuntately, most Cordova plugins are incorporated into your project when the project is built for a device, not when you are testing through the browser. In most cases you will access the plugins functionality through the plugins namespace on Window:

window.plugins.somePlugin.doSomething();

or through a global object that is made available by the plugin:

someGlobal.doSomething();

…but TypeScript doesn’t know about this, so it complains:

error TS2339: Property 'plugins' does not exist on type 'Window'.

Fortunately, there’s an easy way to get around this – we just need to tell TypeScript what’s up. To get around the issue with Window, you can just declare an any type directly on the window, i.e:

(<any>window).plugins.somePlugin.doSomething();

or in the case of a global object, you can declare it using:

declare var someGlobal;

above the @Component decorator. It is common to do this for the cordova global, i.e. declare var cordova;. Using those two steps should get your around most TypeScript issues you will face. However, keep in mind that the functionality still doesn’t exist in the browser, so even though your application will build successfully (which is important to be able to deploy it to a device in the first place), if you are testing through the browser your application will still break if you are making a call to the plugin.

Of course, if you’d really like to see the plugin you want to use supported in Ionic Native you can even add support for it yourself.

  • I tried, albeit briefly, and failed to do this just the other day.
    Perfect timing! Although I’m curious, if using TypeScript (yet another
    thing I’m new to and questioning whether it’s worth the effort) are
    there extra steps to get the plugins “included” in the build?

    Thanks!
    Brian

  • Mark McGreevy

    Greetings Josh..

    I have a quick question regarding ionic2 and Cordova.. The following works fine except that in any of the cordova functions I can’t access my variables. eg this.dbname is undefined in the following example.

    Any suggestions..?

    Thanks in advance for your time..
    this.dbname = ‘test.db’;
    this.openDB();
    openDB(){
    let options={name: this.dbname, iosDatabaseLocation: ‘default’};
    this.db = window.sqlitePlugin.openDatabase(options, function() {
    console.log(this.dbname+’ opened ok’);
    },function(err){
    console.log(‘Open database ERROR: ‘ + JSON.stringify(err));
    });
    }

    • The scope of `this` is different inside of callback functions, since you’re using Ionic 2 just use the fat arrow syntax to get around this problem, i.e:

      openDatabase(options, () => {
      console.log(this.dbname);
      }, () => {
      console.log(“error”);
      });

      • Mark McGreevy

        Thanks for the quick reply. Looking forward to your book..
        Cheers..

  • Thanks for the great post!

    Can I use Ionic Native as well with Ionic 1? Or is it just for Ionic 2?

    • It’s made for ES6/TypeScript so it’s just for Ionic 2. You should use ngCordova for Ionic 1.

  • roberto

    Great tutorials on your website. Only one thing… It seems that Ionic2/Angular2 is going to turn definitively on TS instead EC6. I honestly prefer Typescript, more concise though the difference is really slightly. But I see the “export” class do not need “static get parameters()” function and the code looks a little clearer. My first question: what do you think about it?. The second: I’m going to buy your guide, but I would like to know if it is based on ECM6 or Typescript… because in the free chapter (decorators) I don’t see what language you use

  • Pingback: Ionic 2 First Look Series: Your First Ionic 2 App Explained | HTML5 Mobile Tutorials | Ionic, Phaser, Sencha Touch & PhoneGap()

  • Pingback: Integrating Ionic 2 with the Dropbox API - Part 2 | HTML5 Mobile Tutorials | Ionic, Phaser, Sencha Touch & PhoneGap()

  • Adriaan Botha

    Great article, I am a bit unsure how to use the cordova-plugin-ms-adal, since I tried doing all of the above. It keeps on saying Microsoft is not ‘defined’

    • Make sure the plugin is successfully installed by running ‘ionic plugin ls’. Next make sure you are only trying to access the plugin after the device is ready (i.e. using platform.ready()). Also, remember that the plugin will only work after building with Cordova and running on a real device, it won’t work through the browser with ‘ionic serve’.

      • Adriaan Botha

        So if I got it working in my Angular JS 2 app, can I reuse that part to make it working sinde the IONIC 2 web part, and then use cordova to make it work for devices ? or is there a better way perhaps. Since I tripped over typings and it doesn’t see the AuthenitcateContext part when I do this ? Any idea’s perhaps on the typings part perhaps. Thanks so much for you input

      • Hieu Luong

        Have you solved it? I have the same problem. 🙁

  • I am currently working in Ionic 1. I am just getting started with ionic 2. i am confused what language to use in ionic 2 js,tc and ec6 .

    i don’t know where should i start from to work with ionic 2.

  • KelviROLEX

    Hello Josh,
    Thank you for this great tutorial. I am currently new to ionic and I started learning ionic 2, weeks back, my major problem is adding cordova plugins, if I run cordova add plugin name of plugins on my cli it will add the plugin, but where am confused is trying to import the plugin to my .ts file, let’s say I have this plugin https://github.com/initialxy/cordova-plugin-themeablebrowser, after adding the plugin to my project, I really don’t know the folder to import it from in my .ts eg import {Theameable} from “”, don’t know where to locate it from. I have tried every folder but am getting error message that it’s not located there. Pls can u just give me a clue on how to import plugins after adding them. Thanks

  • kenny jack

    Hi,

    I just want to try out how the ionic native plugins work. And i follow all the step and run “ionic serve”. In my console log i couldn’t have the geolocation.
    instead having this error

    404 error cannot found
    .
    Please help.

  • kamini

    Hi I want to use Paypal Cordova Plugin, but don’t understand how to import it.
    https://github.com/paypal/PayPal-Cordova-Plugin

    • Ramon Vicente

      i need this tooo

      • Arvind Patil

        We have designed custom TCP/IP printer plugin ,it worked with ionic 2 beta19 but now we upgraded to beta37 ,same plugin is giving us error.Can you tell us how to add custom plugin to ionic-native

  • Pingback: Talking Progressive Web Apps with Ionic's Justin Willis | joshmorony - Build Mobile Apps with HTML5()

  • Thomas Kientz

    How can we use “window.plugins”

    I get the TS error “Property ‘plugins’ does not exist on type ‘Window’.”

    • Flllexa

      You need write: (window).plugins

  • Pingback: Integrating Native Google Maps into an Ionic 2 Application | joshmorony - Build Mobile Apps with HTML5()

  • dhemitus

    i build and i run it on my device but not shows anything.

  • Pingback: Ionic GO - Create a Pokémon GO Style Interface in Ionic 2 | joshmorony - Build Mobile Apps with HTML5()

  • Thanks for your article. I’ve also wrote some articles about ionic 2 camera plugin
    Access Gallery: https://phonegappro.com/ionic2-tutorial/access-photo-gallery-using-ionic-2/
    Access Camera: https://phonegappro.com/ionic2-tutorial/access-camera-using-ionic-2/

  • Punleu Chomnan

    I’m using this plugin https://ionicframework.com/docs/v2/native/cardio/
    I’m not sure how to include it in my Ionic2 with typescript.

    Can anyone guild me please?

  • How to create draggable marker ? & get location after drag ?

  • Daniel Archer

    hey bro. typo (or an update?) here:
    “Let’s add it to the automatically generated home page in home.ts” –> “Let’s add it to the automatically generated app components page in app.component.ts”

  • Surya Khanal

    Is it possible to make native home widget with ionic 2?. I have found a plugin called cordova-plugin-ace. As in the doc as my understanding using this plugin we can make widget with the cordova base app. Please can you explain or can have some tutorial in the future?