Ionic Storage Module: Ionic 2

This video tutorial is an update to our previous tutorial Ionic Storage: Ionic 2.

Major Changes To Note
Previously we use to import Storage class inside src/app/app.module.ts file and we would list it as one of the providers. But now we need to import IonicStorageModule class inside src/app/app.module.ts file and list it inside imports array. That’s the only difference in implementing Ionic Storage, everything else is as described in Ionic Storage: Ionic 2 video tutorial.

Database

In this video tutorial only concentrate on src/app/app.module.ts file and for implementing storage set and get method refer Ionic Storage: Ionic 2 video tutorial itself.

Ionic Storage Module In Ionic 2 (Update)



YouTube Link: http://www.youtube.com/watch?v=lKsspk5kafE [Watch the Video In Full Screen.]



src/app/app.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
 
import { IonicStorageModule } from '@ionic/storage';
 
@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    IonicModule.forRoot(MyApp),
    IonicStorageModule.forRoot()
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

Here we import IonicStorageModule class and list it inside imports array. We can also specify database name and database preference as follows:

imports: [
    IonicModule.forRoot(MyApp),
    IonicStorageModule.forRoot({
      name: '__mydbName',
      driverOrder: ['sqlite', 'indexeddb', 'websql']
    })
  ]

Now implementing get and set methods wherever we need it. Practically it would be useful inside a data provider file, but in this tutorial am implementing inside a normal page, so that I keep the complexities out for this basic lesson.

src/pages/home/home.ts

import { Component } from '@angular/core';
 
import { NavController } from 'ionic-angular';
 
import { Storage } from '@ionic/storage';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 
  constructor(public storage: Storage, public navCtrl: NavController) {
    this.storage.ready().then(() => {
     this.storage.set('myKey', 10);
    });
  };
 
  getValues(){
     this.storage.get('myKey').then((data) => {
       if(data != null)
       {
         console.log(data);
       }
     });
  };

Here we import Storage class and create an instance of it. We check if the storage is ready. Once its ready it returns/resolves a promise. So now we can set value using this.storage.set() method. We can set an object, an array or a strong value or simply a number.

We can get the value by using its get method, which returns the value stored in the key as promise. If nothing is stored in the key, it returns null.

Using Ionic Native: Ionic 2

Today lets learn about an important project which helps us use 130+ native mobile SDK features in our Ionic application through simple JavaScript interfaces – Ionic Native.

ionic native ionic2

Ionic Native is a TypeScript wrapper for Cordova/PhoneGap plugins that make adding any native functionality you need to your Ionic 2 mobile app easy. Ionic Native wraps plugin callbacks in a Promise or an Observable, providing a common interface for all plugins and ensuring that native events trigger change detection in Angular 2.

Related Read:
Ionic 2 Starter Templates.
Adding AdMob In Ionic 2.

Using ‘Ionic Native’ In Ionic 2 Applications



YouTube Link: http://www.youtube.com/watch?v=SM54loG63ks [Watch the Video In Full Screen.]



There are two steps required to use Ionic Native in our project
1. Install the Ionic Native package for each plugin you want to add.
2. Install the plugin using Cordova or Ionic CLI.

For example:
If we want to add AdMob plugin to our application:
Step 1: Add/ Install Specific Ionic Native package

npm install --save @ionic-native/ad-mob

Step 2: Add / install the plugin using Cordova or Ionic CLI.

ionic plugin add cordova-plugin-admobpro

Additional Implementation
Listing Plugin Class as Provider: src/app/app.module.ts

import { AdMob } from '@ionic-native/ad-mob';
import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
 
 
 
@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    AdMob,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

Look at the first import statement in above code snippet. We import AdMob plugin and the way we import is specific to ad-mob and we do not import the whole ionic native script here – thus saving application load time.

Also specify the class name as provider. Because we use the services provided by this class in our application.

Working of plugin: src/app/app.component.ts

import { AdMob } from '@ionic-native/ad-mob';
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
 
import { HomePage } from '../pages/home/home';
 
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage:any = HomePage;
 
  constructor(public admob: AdMob, 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.
 
      this.admob.createBanner({
        adId: 'ca-app-pub-5732334124058455/4262868443',
        isTesting: false,
        autoShow: false
      }).then(() => {
        this.admob.showBanner(8);
      });
 
    });
  }
}

Again, we import AdMob native code wherever we want to implement the service of this plugin. We create instance of the class we want to implement – as constructor argument. Then inside platform.ready() method we call the methods of these classes and implement its services inside our project.

Trouble Shoot
1. If you’re getting ‘plugin not found‘ error. OR Cannot find module “@ionic-native/ “ errors, then follow below commands to fix it.

npm rebuild
npm install

2. Error Message “Provider Not Found:
Make sure to include all the specific packages inside src/app/app.module.ts file and list its class name inside providers array.

ngClass Directive: Ionic 2

Today lets learn how to make use of ngClass angular directive in our Ionic 2 application.

Related Read:
ngIf, index, first, last: Ionic 2

ngClass Directive: Ionic 2



YouTube Link: http://www.youtube.com/watch?v=r1ZRoXBcUfs [Watch the Video In Full Screen.]



Company Names: src/pages/home/home.ts

import { Component } from '@angular/core';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
items: any = [];
  constructor() {
    this.items = [
      'Microsoft',
      'Apple',
      'Oracle',
      'Google',
      'IBM',
      'Tesla',
      'Technotip'
    ];
  }
}

We have an array of company names which is being assigned to variable items.

ngClass angular directive ionic 2

Output
Microsoft
Apple
Oracle
Google
IBM
Tesla
Technotip

CSS Class: src/pages/home/home.scss

page-home {
    .bold{
        font-weight: bolder;
    }
    .normal{
        font-weight: normal;
    }
}

We define two CSS classes which we use to apply for alternate list items – using ngClass directive. Alternatively the list items appear in bold and in normal font weight.

ngClass Directive – using ternary operator: src/pages/home/home.html

< ion-header>
  < ion-navbar>
    < ion-title>
      Company Names
    < /ion-title>
  < /ion-navbar>
< /ion-header>
 
< ion-content padding>
< ion-list no-lines>
  < ion-item *ngFor="let item of items; let i = index;"
             [ngClass]="(i % 2 == 0) ? 'bold' : 'normal'">
    {{i+1}}. {{item}}
  < /ion-item>
< /ion-list>
< /ion-content>

Here we use ternary operator and whenever i % 2 is zero we apply bold class to that item, if not we apply normal class to that list item.

ngClass Directive: src/pages/home/home.html

< ion-header>
  < ion-navbar>
    < ion-title>
      Company Names
    < /ion-title>
  < /ion-navbar>
< /ion-header>
 
< ion-content padding>
< ion-list no-lines>
  < ion-item *ngFor="let item of items; let i = index;"
             [ngClass]="{'bold': (i % 2 == 0)}">
    {{i+1}}. {{item}}
  < /ion-item>
< /ion-list>
< /ion-content>

This is yet another way of doing the same thing which we did using ternary operator above. Here, if i % 2 is equal to zero, then bold class will be applied, if not it won’t be applied.

changing colors: src/pages/home/home.scss

page-home {
    .bold{
        font-weight: bolder;
        color: blue;
    }
    .normal{
        font-weight: normal;
        color: green;
    }
}

Alternatively the list items appear in bold and in normal font weight, along with blue and green colors respectively.

List Item Reordering: Ionic 2

Today lets learn how to implement reordering of list items in Ionic 2, using reorder directive and ionItemReorder event.

We’re using previous day code to implement reordering list items. So please go through these two small video tutorials before continuing .. (if you’re an advance user, then you can directly follow todays video tutorial).

1. Ionic Storage: Ionic 2
2. Pull To Refresh: Ionic 2

ionic 2 list item reorder

In this video tutorial lets learn
1. To build drag and rearrange interface and functionality.
2. Solve the ion-refresher component interference with the reorder directive.
3. Save rearranged data back to the database.

Reordering list items using reorder directive: Ionic 2



YouTube Link: http://www.youtube.com/watch?v=wKq4sKk5DXU [Watch the Video In Full Screen.]



reorder directive
We can implement reorder directive directly on ion-list. This way we apply reordering to the entire items present inside ion-list.

reorder on ion-list: src/pages/home/home.html

 < ion-list no-lines 
           reorder="true" 
           (ionItemReorder)="reorderItems($event);">
   < ion-item *ngFor="let item of items">
     {{item}}
   < /ion-item>
 < /ion-list>

But if we have ion-header, ion-footer and other items inside the list for which we do not want the reorder directive to be applied.
reorder on ion-item-group: src/pages/home/home.html

 < ion-list no-lines>
   < ion-list-header>Company Names
   < ion-item-group reorder="true" (ionItemReorder)="reorderItems($event);">
    < ion-item *ngFor="let item of items">
     {{item}}
    < /ion-item>
   < /ion-item-group>
 < /ion-list>

In that case we need to group those items on which we want the reordering, and then apply reorder directive on that group, as shown in above example.

reordering code: src/pages/home/home.ts

reorderItems(indexes){
 let element = this.items[indexes.from];
 this.items.splice(indexes.from, 1);
 this.items.splice(indexes.to, 0, element);
};

When the item is dragged and dropped to the new position, (ionItemReorder) event is emitted and this event also provides initial and new position index of the reordered item. Using this, we reorder the list items.

Above code snippet is a simple JavaScript code, where we first get the actual item value which is being reordered(using its index value – indexes.from) and store it in a temporary variable. Next we remove that item from the list. Finally we place that element in the new position. All these operation is done using simple JavaScript splice method.

Helper Function: src/pages/home/home.ts

import { reorderArray } from 'ionic-angular';
 
class MyComponent {
  items = [];
 
  reorderItems(indexes) {
    this.items = reorderArray(this.items, indexes);
  }
}

Ionic 2 also provides helper function called reorderArray to reorder the array of items. Here we import the helper class and then use it to reorder the array of items.

Helper Function: src/pages/home/home.html

< ion-list>
  < ion-list-header>Header< /ion-list-header>
  < ion-item-group reorder="true" (ionItemReorder)="$event.applyTo(items)">
    < ion-item *ngFor="let item of items">{{ item }}< /ion-item>
  < /ion-item-group>
< /ion-list>

We can execute helper function inside template as well, as shown above.

Reordering ON and OFF
src/pages/home/home.html

< ion-header>
  < ion-navbar>
    < ion-title>
      Company Names
    < /ion-title>
    < ion-buttons end>
      < button ion-button small clear (click)="actionBtn();">
        {{btnName}}
      < /button>
    < /ion-buttons>
  < /ion-navbar>
< /ion-header>
 
< ion-content padding>
 < ion-list no-lines>
   < ion-list-header>Company Names< /ion-list-header>
   < ion-item-group reorder="{{flag}}" 
                    (ionItemReorder)="reorderItems($event);">
   < ion-item *ngFor="let item of items">
     {{item}}
   < /ion-item>
   < /ion-item-group>
 < /ion-list>
< /ion-content>

Note that we have a button inside ion-header. We switch the value of btnName variable between ‘edit’ and ‘Done’ alternatively when the user clicks on it. Also we have assigned a variable(flag) to reorder directive. flag is of type Boolean and it also switches between ‘true’ and ‘false’ when the user clicks on btnName button. This way we enable and disable the visual drag and rearrange interface on the list items.

src/pages/home/home.ts

import { Component } from '@angular/core';
 
import { NavController } from 'ionic-angular';
import { Storage } from '@ionic/storage';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
items: any;
btnName: any = 'edit';
flag: any = false;
  constructor(public navCtrl: NavController, public storage: Storage) {
    this.doRefresh(0);
  };
doRefresh(refresher){
    this.storage.get('myStore1').then((data) => {
      this.items = data;
 
      if(refresher != 0)
         refresher.complete();
    }); 
};
reorderItems(indexes){
 let element = this.items[indexes.from];
 this.items.splice(indexes.from, 1);
 this.items.splice(indexes.to, 0, element);
};
actionBtn(){
 if(this.btnName == 'edit')
 {
   this.btnName = 'Done';
   this.flag    = true;
 }
 else
 {
   this.btnName = 'edit';
   this.flag    = false;
   this.storage.set('myStore1', this.items);
 }
};
 
}

Here we initialize the btnName with a value of ‘edit’ and flag as ‘false’. So initially, the drag and rearrange interface will be disabled. Once the user clicks on the ‘edit’ button present inside ion-header, the visual drag and rearrange interface appears. After the rearrangement of the item is finished user needs to click on ‘Done’ button and we save the rearranged list items to our database. This way we can persist the rearranged data.

We could even save the data to database inside reorderItems() method itself, so that the data gets saved when the user drags and drops the item in its new position. Without the need for the user to click on ‘Done’ button.

actionBtn() method

actionBtn(){
 if(this.btnName == 'edit')
 {
   this.btnName = 'Done';
   this.flag    = true;
 }
 else
 {
   this.btnName = 'edit';
   this.flag    = false;
   this.storage.set('myStore1', this.items);
 }
};

Initially variable ‘btnName’ will be ‘edit’ and flag will be ‘false’. When the user clicks on ‘edit’ button, the label name changes to ‘Done’ and the flag value changes to ‘true’. By this, the drag and rearrange interface appears on the list items. Once the arrangement is done, the user needs to click on the button ‘Done’. When the user clicks on ‘Done’ button, the button label or name changes back to ‘edit’ and the visual drag and rearrange interface gets disabled and optionally we save the rearranged data back to the database.

item reordering and ion-refresher conflict

< ion-header>
  < ion-navbar>
    < ion-title>
      Company Names
    < /ion-title>
    < ion-buttons end>
      < button ion-button small clear (click)="actionBtn();">
        {{btnName}}
      < /button>
    < /ion-buttons>
  < /ion-navbar>
< /ion-header>
 
< ion-content padding>
  < ion-refresher (ionRefresh)="doRefresh($event);">
    < ion-refresher-content 
      pullingText="Pull to refresh"
      pullingIcon="arrow-dropdown"
      refreshingSpinner="circles"
      refreshingText="..fetching">
    < /ion-refresher-content>
 < /ion-refresher>
 
 < ion-list no-lines>
   < ion-list-header>Company Names< /ion-list-header>
   < ion-item-group reorder="true" 
                    (ionItemReorder)="reorderItems($event);">
   < ion-item *ngFor="let item of items">
     {{item}}
   < /ion-item>
   < /ion-item-group>
 < /ion-list>
< /ion-content>

This code has both ion-refresher as well as reorder directive. Here when the user tries to drag an item downwards the refresher component gets invoked. To avoid that, we can simply disable ion-refresher when we enable reordering and enable ion-refresher when we disable reordering, as shown in below code.

Fixed: ion-refresher & item reorder

< ion-header>
  < ion-navbar>
    < ion-title>
      Company Names
    < /ion-title>
    < ion-buttons end>
      < button ion-button small clear (click)="actionBtn();">
        {{btnName}}
      < /button>
    < /ion-buttons>
  < /ion-navbar>
< /ion-header>
 
< ion-content padding>
  < ion-refresher (ionRefresh)="doRefresh($event);" 
                  *ngIf="flag == false">
    < ion-refresher-content 
      pullingText="Pull to refresh"
      pullingIcon="arrow-dropdown"
      refreshingSpinner="circles"
      refreshingText="..fetching">
    < /ion-refresher-content>
 < /ion-refresher>
 
 < ion-list no-lines>
   < ion-list-header>Company Names< /ion-list-header>
   < ion-item-group reorder="{{flag}}" 
                    (ionItemReorder)="reorderItems($event);">
   < ion-item *ngFor="let item of items">
     {{item}}
   < /ion-item>
   < /ion-item-group>
 < /ion-list>
< /ion-content>

Full Free Source Code: src/pages/home/home.html

< ion-header>
  < ion-navbar>
    < ion-title>
      Company Names
    < /ion-title>
    < ion-buttons end>
      < button ion-button small clear (click)="actionBtn();">
        {{btnName}}
      < /button>
    < /ion-buttons>
  < /ion-navbar>
< /ion-header>
 
< ion-content padding>
  < ion-refresher (ionRefresh)="doRefresh($event);" 
                  *ngIf="flag == false">
    < ion-refresher-content 
      pullingText="Pull to refresh"
      pullingIcon="arrow-dropdown"
      refreshingSpinner="circles"
      refreshingText="..fetching">
    < /ion-refresher-content>
 < /ion-refresher>
 
 < ion-list no-lines>
   < ion-list-header>Company Names< /ion-list-header>
   < ion-item-group reorder="{{flag}}" 
                    (ionItemReorder)="reorderItems($event);">
   < ion-item *ngFor="let item of items">
     {{item}}
   < /ion-item>
   < /ion-item-group>
 < /ion-list>
 
  < p>
    < ion-label fixed>Company Name< /ion-label>
    < ion-input type="text" name="company" [(ngModel)]="company">
    < /ion-input>
    < button ion-button (click)="save(company);">Add< /button>
  < /p>
< /ion-content>

Full Free Source Code: src/pages/home/home.ts

import { Component } from '@angular/core';
 
import { NavController } from 'ionic-angular';
import { Storage } from '@ionic/storage';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
items: any;
btnName: any = 'edit';
flag: any = false;
  constructor(public navCtrl: NavController, public storage: Storage) {
    this.doRefresh(0);
  };
doRefresh(refresher){
    this.storage.get('myStore1').then((data) => {
      this.items = data;
 
      if(refresher != 0)
         refresher.complete();
    }); 
};
reorderItems(indexes){
 let element = this.items[indexes.from];
 this.items.splice(indexes.from, 1);
 this.items.splice(indexes.to, 0, element);
};
actionBtn(){
 if(this.btnName == 'edit')
 {
   this.btnName = 'Done';
   this.flag    = true;
 }
 else
 {
   this.btnName = 'edit';
   this.flag    = false;
   this.storage.set('myStore1', this.items);
 }
};
  save(val){
    console.log('data added '+val);
    this.storage.get('myStore1').then((data) => {
      if(data != null)
      {
        data.push(val);
        this.storage.set('myStore1', data);
      }
      else
      {
        let array = [];
        array.push(val);
        this.storage.set('myStore1', array);
      }
    });
  };
}

Example Application:
We’ve implemented the same code in one of our application ‘RSS Reader‘. Go to ‘Feed’ tab and add few blog / news sites rss feeds and the refresh the ‘Feed’ tab to see ‘list item reordering’ in action.

Pull To Refresh: Ionic 2

In today’s video tutorial, I’ll show you how to add ‘pull to refresh’ functionality to your Ionic 2 application. This works on the web(maybe as a progressive web app), on your real device, and even in simulators!

Before proceeding with today’s tutorial, please make sure to watch and understand Ionic Storage: Ionic 2. Because we’re implementing ‘pull to refresh’ for the same code we built for that tutorial.

Today we shall learn
1. How to add ‘pull to refresh’ functionality.
2. Also to customize the ‘pull to refresh’ outlook assets – like icons, text etc.

Adding ‘Pull To Refresh’ Functionality: Ionic 2



YouTube Link: http://www.youtube.com/watch?v=LBZQ-jHuQq0 [Watch the Video In Full Screen.]



Ion Refresher Code: src/pages/home/home.html

< ion-content>
  < ion-refresher (ionRefresh)="doRefresh($event);">
    < ion-refresher-content 
      pullingText="Pull to refresh"
      pullingIcon="arrow-dropdown"
      refreshingSpinner="circles"
      refreshingText="..fetching">
    < /ion-refresher-content>
 < /ion-refresher>
< /ion-content>

Here we add ion-refresher as first child of ion-content. This adds pull to refresh functionality on content component.

Once the user pulls down on the content area of the view, doRefresh method is called and it is passed with the refresher event, which has a method called complete(), when called, it collapses whatever is being shown on the screen by ion-refresher-content ( which is the child of ion-refresher ).

ionic refresh pull

Customize pull-to-refresh
We customize the look and feel of the pull to refresh functionality using ion-refresher-content‘s attributes. In our example, we have changed the default icon and have added text for both when the user pulls the content area down and while the fresh content is being fetched(before the complete() method is called in the home.ts component).

Related Read: ion-spinner Component: Ionic 2

ionic refresh leave

Note:
If we do not explicitly assign or change attributes on ion-refresher-content, it’ll behave according to the defaults of the operating system it’s working on.

Ion Refresher Code – default values for platforms: src/pages/home/home.html

< ion-content>
  < ion-refresher (ionRefresh)="doRefresh($event);">
    < ion-refresher-content>
    < /ion-refresher-content>
 < /ion-refresher>
< /ion-content>

doRefresh() method definition: src/pages/home/home.ts

doRefresh(refresher){
    this.storage.get('myStore').then((data) => {
      this.items = data;
 
      if(refresher != 0)
         refresher.complete();
    }); 
};

Once the doRefresh method is invoked by the view, we fetch the data and once done, we call complete() method on refresher object, which collapses whatever visual cues ionic is providing to the end user via ion-refresher-content.

Full Free Source Code: src/pages/home/home.html

< ion-header>
  < ion-navbar>
    < ion-title>
      Ionic Blank
    < /ion-title>
  < /ion-navbar>
< /ion-header>
 
< ion-content padding>
  < ion-refresher (ionRefresh)="doRefresh($event);">
    < ion-refresher-content 
      pullingText="Pull to refresh"
      pullingIcon="arrow-dropdown"
      refreshingSpinner="circles"
      refreshingText="..fetching">
    < /ion-refresher-content>
 < /ion-refresher>
  < p *ngFor="let item of items">
    {{item}}
  < /p>
  < p>
    < ion-label fixed>Company Name< /ion-label>
    < ion-input type="text" name="company" [(ngModel)]="company">
    < /ion-input>
    < button ion-button (click)="save(company);">Add< /button>
  < /p>
< /ion-content>

Full Free Source Code: src/pages/home/home.ts

import { Component } from '@angular/core';
 
import { NavController } from 'ionic-angular';
import { Storage } from '@ionic/storage';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
items: any;
  constructor(public navCtrl: NavController, public storage: Storage) {
    this.doRefresh(0);
  };
doRefresh(refresher){
    this.storage.get('myStore').then((data) => {
      this.items = data;
 
      if(refresher != 0)
         refresher.complete();
    }); 
};
  save(val){
    console.log('data added '+val);
    this.storage.get('myStore').then((data) => {
      if(data != null)
      {
        data.push(val);
        this.storage.set('myStore', data);
      }
      else
      {
        let array = [];
        array.push(val);
        this.storage.set('myStore', array);
      }
    });
  };
}

Here we need to call doRefresh() method inside the constructor too, without which the application will not have any data when its loaded for the first time – until the user pulls the content view and invokes doRefresh() method. To avoid such inconvenience, we call doRefresh() method inside the constructor and pass in ZERO as its parameter – this way we can bypass calling complete() method whenever the data being passed to doRefresh() method is ZERO.

Ionic Storage: Ionic 2

Ionic 2 comes with Ionic Storage library which makes use of storage engines based on its availability and its priority. For example, in native device it uses SQLite if available, if not it’ll fall back to use localstorage or IndexedDB – again, based on its availability. If the app is being run in the web or as a Progressive Web App, Storage will attempt to use IndexedDB, WebSQL, and localstorage, in that order.

Update:

Ionic has made slight changes in how your import Ionic Storage inside app.module.ts file. You can find it at Ionic Storage Module: Ionic 2. Other than how you import Ionic Storage in app.module.ts file, everything is same as present in this(Ionic Storage: Ionic 2) video tutorial.

In this video lets learn how to store and retrieve JSON data in array format using Ionic 2 Storage with a very simple example.

databases

localstorage, WebSQL and IndexedDB
Since Ionic uses browser to render the application, we have access to browser based storage engines like localstorage, WebSQL and IndexedDB. But these storage engines are not reliable. If the device is running on low disk-space and the operating system decides to clear some data, then it might even clear the data stored in these storage engines.

SQLite
SQLite is query based RDBMS like Storage System for Mobile Devices. You can create, read, update and delete records just like in RDBMS. If you want to store/persist serious data locally, then you can relay on SQLite. Ionic 2 doesn’t ship with this by default – we can use cordova plugin to make use of SQLite.

cordova plugin add cordova-sqlite-storage

Once we install this cordova plugin, Ionic 2 Storage library will priorities SQLite and make use of it instead of localstorage or IndexedDB.

Remember, Ionic Storage uses SQLite only on the native device. If you run the same application on the web maybe as a Progressive Web App, Ionic Storage will switch to use IndexedDB, WebSQL, and localstorage, in that order.

Persisting Data with Ionic Storage: Ionic 2



YouTube Link: http://www.youtube.com/watch?v=Cnj9fQCyflY [Watch the Video In Full Screen.]



View Code: src/app/app.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { Storage } from '@ionic/storage';
 
@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [Storage, {provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}

Make sure to import Ionic Storage in app.module.ts file and list it as one of the providers.

Get Stored Data: src/pages/home/home.ts

  constructor(public navCtrl: NavController, public storage: Storage) {
    this.storage.get('myStore').then((data) => {
      this.items = data;
      console.log(data);
    });
  };

Make sure to import the library first inside home.ts component. Next, create a reference variable for Storage class. Now access the get method of Storage class. Using get method, get the value assocated with the given key. This returns a promise. Once the promise is resolved we get the stored data. If the key is being used for the first time and nothing has been stored yet, then it returns null.

Set Data: src/pages/home/home.ts

this.storage.set('myStore', value);

Set the value for the given key. In my case, am using a key called myStore.

Full Free Source Code: src/pages/home/home.ts

import { Component } from '@angular/core';
 
import { NavController } from 'ionic-angular';
import { Storage } from '@ionic/storage';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
items: any;
  constructor(public navCtrl: NavController, public storage: Storage) {
    this.storage.get('myStore').then((data) => {
      this.items = data;
      console.log(data);
    });
  };
  save(val){
    console.log('data added '+val);
    this.storage.get('myStore').then((data) => {
      if(data != null)
      {
        data.push(val);
        this.storage.set('myStore', data);
      }
      else
      {
        let array = [];
        array.push(val);
        this.storage.set('myStore', array);
      }
    });
  };
}

First we import the Storage library at the top. Next create a reference variable called storage. Inside the constructor we get / fetch the stored data and assign it to a variable called items, which we iterate through and display on the home.html view.

save() method
When the user enters some data in the input field(on the view – home.html) and submits, we check the previously stored data, if present, retrieve it, append the new data and then stored / set it back to the same key.

Full Free Source Code: src/pages/home/home.html

< ion-header>
  < ion-navbar>
    < ion-title>
      Ionic Blank
    < /ion-title>
  < /ion-navbar>
< /ion-header>
 
< ion-content padding>
  < p *ngFor="let item of items">
    {{item}}
  < /p>
  < p>
    < ion-label fixed>Company Name< /ion-label>
    < ion-input type="text" name="company" [(ngModel)]="company">
    < /ion-input>
    < button ion-button (click)="save(company);">Add< /button>
  < /p>
< /ion-content>

Here we iterate through the variable items and then display individual array item on the view. We also have a input field where user enters company name and once he/she hits on Add button the data gets saved in storage engine via Ionic 2 Storage.

Other Member functions of Ionic 2 Storage Class
remove(key); – Remove any value associated with this key.
clear(); – Clears the entire key value store. (Be very careful while using it.)
length(); – returns the number of keys stored.
keys(); – returns the keys in the store.
forEach(iteratorCallback) – Iterate through each key,value pair.

Facebook Native Ads Clickable Area: Ionic 2

Today lets learn how to code the clickable area of Facebook Native Ad Unit. Before proceeding with today’s tutorial, please visit yesterdays tutorial and learn how to request and display the Native Ad creative inside Ionic 2 application.

Facebook Native Ads: Ionic 2

In todays video tutorial lets learn:
1. Removing top left corner green patch – clickable area problem.
2. Aligning the clickable area to the Native Ad Unit creative properly.
3. Make sure the top left corner clickable area doesn’t appear once again when we change the device orientation.
4. Removing clickable area once the user switches to other views.
5. Why doesn’t your app show Facebook Native Ads all the time – why is fill rate low?

Audience Network’s Native Ads Clickable Area: Ionic2



YouTube Link: http://www.youtube.com/watch?v=7Zfe40dbjgs [Watch the Video In Full Screen.]



View Code: src/pages/home/home.html

    < ion-card id="native">
      < img src="" id="adCover" style="max-width: 100%; height: auto;" />
      < ion-card-content text-wrap>
        < ion-item>
          < ion-avatar item-left>
            < img src="" id="adIcon" />
          < /ion-avatar>
          < h2 id="adTitle">
          < p id="adBody">
        < /ion-item>
        < ion-row>
          < ion-col center text-left width-70 small style="font-size: x-small;">
            < span id="adSocialContext" small>< /span>
          < /ion-col>
          < ion-col center text-right width-30>
            < button ion-button small color="secondary" id="adBtn">
            < /button>
          < /ion-col>
        < /ion-row>
      < /ion-card-content>
    < /ion-card>

Here am adding a simple ion-card item with cover image and ion-avatar. We’ve added id’s to each of the elements and will fill the value once the ad data is emitted by onAdLoaded event.

updateXY() method src/pages/home/home.ts

  updateXY(left, top){
           var h, w, x, y;
           var d = document.getElementById('native');
           w = d.clientWidth;
           h = d.clientHeight;
           x = d.offsetLeft - left;
           y = d.offsetTop - top;
 
          if(FacebookAds)
            FacebookAds.setNativeAdClickArea('763416880384578_1139417452784517', x, y, w, h);
  };

Here we dynamically fetch the ad display containers width and height, and then x and y axis values of the display component.

When we scroll the application vertically only y value changes and x value remains constant, when we scroll the view horizontally x value changes and y value remains constant. In most of the application scrolling will only be available vertically.

Finally, we pass x, y, w, h value to setNativeAdClickArea() method along with the Native Ad Units ID as its first parameter.

src/pages/home/home.ts

import { Component} from '@angular/core';
 
import { NavController } from 'ionic-angular';
 
import { Platform } from 'ionic-angular';
 
declare var FacebookAds: any;
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  constructor(public navCtrl: NavController, public platform: Platform) {
    platform.ready().then(() => {
 
 
    });
  };
  updateXY(left, top){
          var d;
          var h, w, x, y;
           d = document.getElementById('native');
           w = document.getElementById('native').clientWidth;
           h = document.getElementById('native').clientHeight;
           x = d.offsetLeft - left;
           y = d.offsetTop - top;
 
          if(FacebookAds)
            FacebookAds.setNativeAdClickArea('763416880384578_1139417452784517', x, y, w, h);
  };    
  ionViewDidEnter(){
    this.platform.ready().then(() => {
        if(FacebookAds)
        {
          FacebookAds.createNativeAd('763416880384578_1139417452784517', function(data){ 
                      document.addEventListener("onAdLoaded", function(data){ 
                        let temp: any = data; 
                        if(temp.adType == "native") 
                        { 
                          document.getElementById('adIcon').setAttribute("src", decodeURIComponent(temp.adRes.icon.url));
                          document.getElementById('adCover').setAttribute("src", decodeURIComponent(temp.adRes.coverImage.url));
                          document.getElementById('adTitle').innerHTML = temp.adRes.title;
                          document.getElementById('adBody').innerHTML = temp.adRes.body;
                          document.getElementById('adSocialContext').innerHTML = temp.adRes.socialContext;
                          document.getElementById('adBtn').innerHTML = temp.adRes.buttonText;
                        }
                      });
          }, function(err) { alert(JSON.stringify(err)); });
        }
   });
  };
}

Now we need to access the view scrolling by the user and then dynamically determine the updated x, y coƶrdinates, so that we can update the current clickable area.

Content Reference
To get reference to the content component from a pages logic, we can use angular’s @ViewChild annotation and create a variable of type Content and subscribe to its scrolling event. And then pass the x(left offset) and y(top offset) values of the screen to UpdateXY() method, so that it can determine the current position of the Native Ad Unit Creative on the mobile screen.

src/pages/home/home.ts

import { Component, ViewChild } from '@angular/core';
 
import { NavController, Content } from 'ionic-angular';
 
import { Platform } from 'ionic-angular';
 
declare var FacebookAds: any;
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  @ViewChild(Content) content: Content;
  constructor(public navCtrl: NavController, public platform: Platform) {
    platform.ready().then(() => {
 
        this.content.ionScroll.subscribe((data) => { 
              this.updateXY(data.scrollLeft, data.scrollTop);
        }); 
 
    });
  };
  updateXY(left, top){
          var d;
          var h, w, x, y;
           d = document.getElementById('native');
           w = document.getElementById('native').clientWidth;
           h = document.getElementById('native').clientHeight;
           x = d.offsetLeft - left;
           y = d.offsetTop - top;
 
          if(FacebookAds)
            FacebookAds.setNativeAdClickArea('763416880384578_1139417452784517', x, y, w, h);
  };    
  ionViewDidEnter(){
    this.platform.ready().then(() => {
        if(FacebookAds)
        {
          FacebookAds.createNativeAd('763416880384578_1139417452784517', function(data){ 
                      document.addEventListener("onAdLoaded", function(data){ 
                        let temp: any = data; 
                        if(temp.adType == "native") 
                        { 
                          document.getElementById('adIcon').setAttribute("src", decodeURIComponent(temp.adRes.icon.url));
                          document.getElementById('adCover').setAttribute("src", decodeURIComponent(temp.adRes.coverImage.url));
                          document.getElementById('adTitle').innerHTML = temp.adRes.title;
                          document.getElementById('adBody').innerHTML = temp.adRes.body;
                          document.getElementById('adSocialContext').innerHTML = temp.adRes.socialContext;
                          document.getElementById('adBtn').innerHTML = temp.adRes.buttonText;
                        }
                      });
          }, function(err) { alert(JSON.stringify(err)); });
        }
   });
  };
}

Look at the code present inside the constructor.

Content Scrolling data

        this.content.ionScroll.subscribe((data) => { 
              this.updateXY(data.scrollLeft, data.scrollTop);
        });

we only pass scrollLeft and scrollTop values to updateXY() method. The full data emitted is shown below for your reference.

{"timeStamp":17926.585000000003,
 "scrollTop":9,
 "scrollLeft":0,
 "scrollHeight":660,
 "scrollWidth":412,
 "contentHeight":604,
 "contentWidth":412,
 "contentTop":56,
 "contentBottom":0,
 "startY":21,
 "startX":0,
 "deltaY":-12,
 "deltaX":0,
 "velocityY":1.195171507111251,
 "velocityX":0,
 "directionY":"up",
 "directionX":"right",
 "fixedElement":{},
 "scrollElement":{},
 "contentElement":{},
 "headerElement":{}}

With this code we start getting a nice Native Ad creative, but with a clickable area at the top left corner of the screen. That is because updateXY() method is called only when the user scrolls the screen. So we need to call updateXY() once the view is loaded. Lets pass (0, 0) as (x, y) value to updateXY() as there is no changes in the x, y coƶrdinates initially when the app is loaded. We call updateXY() method inside ionViewDidEnter() method, once the Native Ad emits some data.

top-left-clickable-area-native-ad-facebook

src/pages/home/home.ts

import { Component, ViewChild } from '@angular/core';
 
import { NavController, Content } from 'ionic-angular';
 
import { Platform } from 'ionic-angular';
 
declare var FacebookAds: any;
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  @ViewChild(Content) content: Content;
  constructor(public navCtrl: NavController, public platform: Platform) {
    platform.ready().then(() => {
 
        this.content.ionScroll.subscribe((data) => { 
              this.updateXY(data.scrollLeft, data.scrollTop);
        }); 
 
    });
  };
  updateXY(left, top){
          var d;
          var h, w, x, y;
           d = document.getElementById('native');
           w = document.getElementById('native').clientWidth;
           h = document.getElementById('native').clientHeight;
           x = d.offsetLeft - left;
           y = d.offsetTop - top;
 
          if(FacebookAds)
            FacebookAds.setNativeAdClickArea('763416880384578_1139417452784517', x, y, w, h);
  };    
  ionViewDidEnter(){
   var that = this;
    this.platform.ready().then(() => {
        if(FacebookAds)
        {
          FacebookAds.createNativeAd('763416880384578_1139417452784517', function(data){ 
                      document.addEventListener("onAdLoaded", function(data){ 
                        let temp: any = data; 
                        if(temp.adType == "native") 
                        { 
                          document.getElementById('adIcon').setAttribute("src", decodeURIComponent(temp.adRes.icon.url));
                          document.getElementById('adCover').setAttribute("src", decodeURIComponent(temp.adRes.coverImage.url));
                          document.getElementById('adTitle').innerHTML = temp.adRes.title;
                          document.getElementById('adBody').innerHTML = temp.adRes.body;
                          document.getElementById('adSocialContext').innerHTML = temp.adRes.socialContext;
                          document.getElementById('adBtn').innerHTML = temp.adRes.buttonText;
                          that.updateXY(0, 0);
                        }
                      });
          }, function(err) { alert(JSON.stringify(err)); });
        }
   });
  };
}

Here we invoke updateXY(0, 0) initially once the view is loaded i.e., before the user actually scrolls the view area. This removes the top left green clickable area patch. But then there is misplaced clickable area. Looks like the area misplaced is equal to the height of the header element.

Note: Am using that.updateXY() to invoke member function instead of this.updateXY(). To know why I replaced the keyword this in order to invoke member function: setTimeout and setInterval methods: Ionic 2

facebook-native-ad-clickable-area-header-ionic2

src/pages/home/home.ts

import { Component, ViewChild } from '@angular/core';
 
import { NavController, Content } from 'ionic-angular';
 
import { Platform } from 'ionic-angular';
 
declare var FacebookAds: any;
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  @ViewChild(Content) content: Content;
  constructor(public navCtrl: NavController, public platform: Platform) {
    platform.ready().then(() => {
          this.content.ionScroll.subscribe((data) => { 
              this.updateXY(data.scrollLeft, data.scrollTop);
        }); 
 
    });
  };
  updateXY(left, top){
          var d;
          var h, w, x, y;
           d = document.getElementById('native');
           var headHeight = document.getElementById("headerHeight").clientHeight;
           w = document.getElementById('native').clientWidth;
           h = document.getElementById('native').clientHeight;
           x = d.offsetLeft - left;
           y = d.offsetTop - (top - headHeight);
 
          if(FacebookAds)
            FacebookAds.setNativeAdClickArea('763416880384578_1139417452784517', x, y, w, h);
  };    
  ionViewDidEnter(){
   var that = this;
    this.platform.ready().then(() => {
        if(FacebookAds)
        {
          FacebookAds.createNativeAd('763416880384578_1139417452784517', function(data){ 
                      document.addEventListener("onAdLoaded", function(data){ 
                        let temp: any = data; 
                        if(temp.adType == "native") 
                        { 
                          document.getElementById('adIcon').setAttribute("src", decodeURIComponent(temp.adRes.icon.url));
                          document.getElementById('adCover').setAttribute("src", decodeURIComponent(temp.adRes.coverImage.url));
                          document.getElementById('adTitle').innerHTML = temp.adRes.title;
                          document.getElementById('adBody').innerHTML = temp.adRes.body;
                          document.getElementById('adSocialContext').innerHTML = temp.adRes.socialContext;
                          document.getElementById('adBtn').innerHTML = temp.adRes.buttonText;
                          that.updateXY(0, 0);
                        }
                      });
          }, function(err) { alert(JSON.stringify(err)); });
        }
   });
  };
}

Go to home.html and assign id of headerHeight to the ion-header tag. Now get its clientHeight and subtract it from the current scrollTop of the screen – inside updateXY() method.

facebook-native-ad-clickable-area

On Device Orientation Change
The top left corner green clickable area spot appears once again when the device orientation is changed. To deal with that lets add a listener for orientation change and then call updateXY() method.
src/pages/home/home.ts

 window.addEventListener('orientationchange', function(data){
    if(data.isTrusted == 1)
    {
      this.updateXY(0, 0);
      // You can also get the values of x, y, w, h using javascript and then
      // assign it to the clickablearea method of FacebookAds.
    }
 });

Remove Native Ad
Important: Remove the Native Ad(along with the clickable area) once the user navigates away from the current(Native Ad) view.
src/pages/home/home.ts

  ionViewDidLeave(){
      if(FacebookAds)
         FacebookAds.removeNativeAd('763416880384578_1139417452784517');  
  };

Make sure to call removeNativeAd() method inside ionViewDidLeave() method in order to remove the Native Ad. Other wise, the clickable area still persists and when user clicks on any other app elements the ad gets triggered and this is against Facebooks(or any other adnetworks) ad policy. So in order to play safe and avoid policy violation or termination of your Facebook Audience Network account, make sure you remove the native ad once the user navigates away from that view.

Important Note
Make sure you pass the same native ad units ID to all 3 methods:

var adId = ‘763416880384578_1139417452784517’;
FacebookAds.createNativeAd(adId);
FacebookAds.setNativeAdClickArea(adId, x, y, w, h);
FacebookAds.removeNativeAd(adId);

Still Clickable area is misplaced or not appearing?
Sometimes I observed that the clickable area doesn’t work properly in test mode. But the same code works perfectly while displaying real ads. So if you have set isTesting to true, then make it false.

How to get Test Ads?
You can simply put this code inside your constructor(wrap it around by platform ready method)

FacebookAds.createBanner({adId: '', isTesting: true});

This show start showing test ads, as FacebookAds variable is a global variable to that component. Make sure to change the value of isTesting to false while moving to production or you can simply remove the code if you’re not showing Facebook audience networks banner ads in your application.

Why is my fill rate less than 100% ?
Fill rate refers the number of ads Facebook return compared to the number of ads you request. There are several reasons why not all requests are filled:

  • The person using your app hasn’t logged into the Facebook app in the last 30 days, or the person on your mobile website isn’t logged into Facebook in the same browser. In order to show targeted ads, Audience Network needs to be able to match each person to his or her Facebook profile. Without this match, it can’t fill the request.
  • The person using your app or site has turned off targeted advertising in his or her device settings.
  • Your app or site has requested too many ads in a short period of time. Audience Network limits ad delivery to a maximum of 25 ads served per 30 minutes to a single person. Facebook also limit ad delivery if your app or site requests more than one ad for the same banner placement within 15 seconds.
  • Facebook couldn’t find a relevant ad that matches the targeting and interests of the person using your app or site. Check your filters to make sure you aren’t excluding too many possible advertisers.

Fallback Ad Network
In order to make sure you get near to 100% fill of your ad spot, we need to have a fallback ad network. If Facebooks Audience Network doesn’t have ads to serve to a particular user, then we can invoke some other(alternative/fallback) ad networks Native Ad and fill the ad spot. I’ll be showing it in upcoming video tutorials. Stay subscribed to our blog and our YouTube Channel.

Example Application
We have implemented Facebook Audience Network in one of our applications: RSS Reader
You can use this app to subscribe and keep track of the content you love. You can also subscribe to our blog using the app.

Facebook Native Ads: Ionic 2

Today lets implement Facebook Audience Network’s Native Advertisement in our Ionic 2 application.

Why Native Ad Unit?
A native ad is a custom designed unit that fits seamlessly with your app. If done well, ads can blend in naturally with your interface.

The unique feature of native ads is that they should balance your app’s experience while protecting the integrity of advertisers’ assets.

Related Read: Facebook Banner and Interstitial Ads: Ionic 2

We’ve installed a blank template for this tutorial

ionic start technotip blank --v2

We create a Ionic 2 project by name ‘technotip’ with blank template.

Related Read: Ionic 2 Starter Templates

Audience Network’s Native Ads: Ionic 2



YouTube Link: http://www.youtube.com/watch?v=-wfXpBGbvic [Watch the Video In Full Screen.]



Package version information:

C:\ionic2\technotip>ionic info
 
Your system information:
 
Cordova CLI: 6.1.1
Ionic Framework Version: 2.0.0-rc.4
Ionic CLI Version: 2.1.17
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 0.0.47
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v6.7.0
Xcode version: Not installed

Steps To Follow
Step 1: Install FacebookAds plugin
Step 2: Add Platform
Step 3: Implement Facebook Audience Network’s Native Ad into your Ionic 2 project
Step 4: Install your Ionic 2 app to your device to test Facebook Audience Network’s ads.

Native Advertising

Note: Make sure to navigate to your ionic 2 project folder before executing any commands.
Example: Our Ionic 2 project name is ‘technotip’, which is inside a folder called ionic2. So I execute all commands once I get inside our project folder.

C:\>cd ionic2
C:\ionic2>cd technotip
C:\ionic2\technotip>ionic serve -l -c

Step 1: Install FacebookAds plugin

ionic plugin add cordova-plugin-facebookads

This installs FacebookAds plugin to our Ionic 2 project.

Step 2: Add Platform

ionic platform add android
 
OR
 
ionic platform add ios

If you are developing ios app, than add ios platform(for this, you must be on a Mac). If you’re developing android app, then add android as platform. If you face any difficulty with this step or in installing Ionic framework, please refer to Ionic 2 Starter Templates video tutorial.

Step 3: Implement Facebook Ads into your Ionic 2 project

Native Advertisement

src/pages/home/home.ts

    platform.ready().then(() => {
      if(FacebookAds)
      {
        FacebookAds.createNativeAd('763416880384578_1139417452784517');
        this.start = 1;
      }
 
      document.addEventListener("onAdLoaded", function(data){
        let temp: any = data;
 
        if(temp.adType == "native")
        {
 
          document.getElementById('adIcon').setAttribute("src", temp.adRes.icon.url);
          document.getElementById('adCover').setAttribute("src", temp.adRes.coverImage.url);
          document.getElementById('adTitle').innerHTML = temp.adRes.title;
          document.getElementById('adBody').innerHTML = temp.adRes.body;
          document.getElementById('adSocialContext').innerHTML = temp.adRes.socialContext;
          document.getElementById('adBtn').innerHTML = temp.adRes.buttonText;
        }
 
      });
 
    });

Pass-in native ad units adId to createNativeAd() method. Now add a listener to onAdLoaded event. This event emits bunch of ad data, which we capture and embed into our view.

Here is the data structure(with Facebook Native Test Ad Data) of the emitted data.

 {
    "isTrusted":false,
    "adNetwork":"FacebookAds",
    "adEvent":"onAdLoaded",
    "adType":"native",
    "adId":"763416880384578_1139417452784517",
    "adRes":{"title":"Facebook Test Ad",
             "socialContext":"Get it on Google Play",
             "buttonText":"Install Now",
             "body":"Your ad integration works. Woohoo!",
             "coverImage":{ "url":"https://www.facebook.com/images/ads/network/test_video_banner.png",
                            "width":414,
                            "height":232},
             "icon":{"url":"https://scontent.xx.fbcdn.net/hphotos-xaf1/t39.3079-6/851551_836527893040166_1350205352_n.png",
                     "width":128,
                     "height":128
                     }
             }
}

We check to see if it is a native ad data. If so, we’ll further fetch and assign ad elements to view elements using Javascript.

Full Source Code: src/pages/home/home.ts

import { Component } from '@angular/core';
 
import { NavController } from 'ionic-angular';
 
import { Platform } from 'ionic-angular';
 
declare var FacebookAds: any;
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 
 start: any = 0;
 
  constructor(public navCtrl: NavController, platform: Platform) {
    platform.ready().then(() => {
      if(FacebookAds)
      {
        FacebookAds.createNativeAd('763416880384578_1139417452784517');
        this.start = 1;
      }
 
      document.addEventListener("onAdLoaded", function(data){
        let temp: any = data;
 
        if(temp.adType == "native")
        {
 
          document.getElementById('adIcon').setAttribute("src", temp.adRes.icon.url);
          document.getElementById('adCover').setAttribute("src", temp.adRes.coverImage.url);
          document.getElementById('adTitle').innerHTML = temp.adRes.title;
          document.getElementById('adBody').innerHTML = temp.adRes.body;
          document.getElementById('adSocialContext').innerHTML = temp.adRes.socialContext;
          document.getElementById('adBtn').innerHTML = temp.adRes.buttonText;
        }
 
      });
 
    });
  }
}

Make sure to have global declaration of FacebookAds variable.

View Code: src/pages/home/home.html

  < span id="native" *ngIf="start != 0">
    < ion-card>
      < img src="" id="adCover" style="max-width: 100%; height: auto;" />
      < ion-card-content text-wrap>
        < ion-item>
          < ion-avatar item-left>
            < img src="" id="adIcon" />
          < /ion-avatar>
          < h2 id="adTitle">
          < p id="adBody">
        < /ion-item>
        < ion-row>
          < ion-col center text-left width-70 small style="font-size: x-small;">
            < span id="adSocialContext" small>< /span>
          < /ion-col>
          < ion-col center text-right width-30>
            < button ion-button small color="secondary" id="adBtn">
            < /button>
          < /ion-col>
        < /ion-row>
      < /ion-card-content>
    < /ion-card>
  < /span>

Here am adding a simple ion-card item with cover image and ion-avatar. We’ve added id’s to each of the elements and will fill the value once the ad data is emitted by onAdLoaded event.

Important Note: This is part 1 of implementing Native Ad. Next we need to implement Clickable area of the ad by using setNativeAdClickArea(adId, x, y, w, h) method. If anyone of you have implemented the Clickable area code for Native Ad, then kindly share your knowledge in the comment section – that would help a lot of us.

I’ve implemented Facebook Native Ads Clickable Area: Ionic 2.

Step 4: Install your Ionic 2 app to your device to test Facebook Audience Network ads

ionic run android -l -c

If you include -l and -c options while installing the project to your device, then you’ll get the live reload and log facility. But you need to be connected to the same network as your terminal where you’re ionic 2 project is running. For Example: Same WiFi for your device as well as your terminal. If your computer is using WiFi and your mobile is using service providers Data connection then this won’t work – in such case use ionic run android command, and you won’t get live reload and log information in the terminal.

Troubleshoot
If you’re getting following errors:
cordova_not_found

OR

int org.json.JSONObject.length() on null

Check these 3 things:
1. You’ve installed proper plugin. Check using ionic plugin list command.
2. You’ve declared FacebookAds variable at the top of the component file.
3. You’ve wrapped the plugins service code inside platform.ready() method.

If all above 3 conditions are set right, then try this:

Remove platform and add it once again.

ionic platform rm android
ionic platform add android

Now install the project ionic run android -l -c to your device and check.

Important Note: Most Ionic plugins work only on the real devices, so do not try to test it using browsers.

I’ve implemented Facebook Native Ads Clickable Area: Ionic 2.

Facebook Banner and Interstitial Ads: Ionic 2

Today lets implement Facebook Audience Network’s Banner Ads and Interstitial Ads in our Ionic 2 project.

We’ve installed a blank template for this tutorial

ionic start technotip blank --v2

We create a Ionic 2 project by name ‘technotip’ with blank template.

Related Read: Ionic 2 Starter Templates

Audience Network’s Banner Ads and Interstitial Ads: Ionic 2



YouTube Link: http://www.youtube.com/watch?v=nU5iUw3xwz4 [Watch the Video In Full Screen.]



Package version information:

C:\ionic2\technotip>ionic info
 
Your system information:
 
Cordova CLI: 6.1.1
Ionic Framework Version: 2.0.0-rc.4
Ionic CLI Version: 2.1.17
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 0.0.47
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v6.7.0
Xcode version: Not installed

Steps To Follow
Step 1: Install FacebookAds plugin
Step 2: Add Platform
Step 3: Implement Facebook Audience Network’s Ads into your Ionic 2 project
Step 4: Install your Ionic 2 app to your device to test Facebook Audience Network’s ads.

Facebook Audience Network Ads Ionic2

Note: Make sure to navigate to your ionic 2 project folder before executing any commands.
Example: Our Ionic 2 project name is ‘technotip’, which is inside a folder called ionic2. So I execute all commands once I get inside our project folder.

C:\>cd ionic2
C:\ionic2>cd technotip
C:\ionic2\technotip>ionic serve -l -c

Step 1: Install FacebookAds plugin

ionic plugin add cordova-plugin-facebookads

This installs FacebookAds plugin to our Ionic 2 project.

Step 2: Add Platform

ionic platform add android
 
OR
 
ionic platform add ios

If you are developing ios app, then add ios platform(for this, you must be on a Mac). If you’re developing android app, then add android as platform. If you face any difficulty with this step or in installing Ionic framework, please refer to Ionic 2 Starter Templates video tutorial.

Step 3: Implement Facebook Ads into your Ionic 2 project
1. Banner Ads

To show banner ads in all the views of our app, we need to code it inside src/app/app.component.ts

   if(FacebookAds)
      {
        let options = {
          adId: '763416880384578_1088816394511290',
          adSize: 'SMART_BANNER',
          isTesting: false,
          autoShow: true
        };
        FacebookAds.createBanner(options, function(data){
          FacebookAds.showBanner(8);
        }, function(err){});
      }

Pass configuration information to createBanner() method as first parameter. Second parameter is a success callback and third parameter is an error callback. Inside success callback, we can call showBanner() method which takes position number as a parameter.

isTesting – takes boolean value. It is set to true while development and set to false in production. Default value is false.

FacebookAds Object Value

{
"AD_SIZE":
    {
        "SMART_BANNER":"SMART_BANNER",
        "BANNER":"BANNER",
        "MEDIUM_RECTANGLE":"MEDIUM_RECTANGLE",
        "FULL_BANNER":"FULL_BANNER",
        "LEADERBOARD":"LEADERBOARD",
        "SKYSCRAPER":"SKYSCRAPER"},
 "AD_POSITION":
    {
        "NO_CHANGE":0,
        "TOP_LEFT":1,
        "TOP_CENTER":2,
        "TOP_RIGHT":3,
        "LEFT":4,
        "CENTER":5,
        "RIGHT":6,
        "BOTTOM_LEFT":7,
        "BOTTOM_CENTER":8,
        "BOTTOM_RIGHT":9,
        "POS_XY":10
    }
}

Configure your FacebookAds options using above values.

Important Note: If you’re placing any Ionic Native Plugins code inside constructor, then make sure to wrap it around Platform.ready() method orelse it’ll start throwing errors. Since code inside constructor executes as soon as the class is instantiated, the external libraries might not yet have loaded, which causes the code inside constructor to break. If we wrap the code inside platform ready, the code executes only after the device platform is ready.

Full Source Code: src/app/app.component.ts

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { HomePage } from '../pages/home/home';
 
declare var FacebookAds: any;
 
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage = HomePage;
  constructor(platform: Platform) {
    platform.ready().then(() => {
      if(FacebookAds)
      {
        let options = {
          adId: '763416880384578_1088816394511290',
          adSize: 'SMART_BANNER',
          isTesting: false,
          autoShow: true
        };
        FacebookAds.createBanner(options, function(data){
          FacebookAds.showBanner(8);
        }, function(err){
          console.log(JSON.stringify(err));
        });
      }
    });
  }
}

Make sure to declare FacebookAds variable(of type any) at the top.

2. Interstitial Ad
We shall invoke an interstitial ad once the user clicks on a button – for demo purpose.

src/pages/home/home.html

  < p>
    < button ion-button (click)="loadAd();">Show Ad< /button>
  < /p>

We’ve added the button to our UI. Once the user clicks on the button, we invoke loadAd() method.

src/pages/home/home.ts

  loadAd(){
    if(FacebookAds)
    {
      let options = {
        adId: '763416880384578_900057893387142'
      };
      FacebookAds.prepareInterstitial(options, function(data){
        FacebookAds.showInterstitial();
      }, function(err){})
    }
  };

we pass interstitial ad units adId to prepareInterstitial() method and then once the success callback is returned we invoke showInterstitial() method.

Full Source Code: src/pages/home/home.ts

import { Component } from '@angular/core';
 
import { NavController } from 'ionic-angular';
 
import { Platform } from 'ionic-angular';
 
declare var FacebookAds: any;
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 
 
  constructor(public navCtrl: NavController, platform: Platform) {
    platform.ready().then(() => {});
  }
  loadAd(){
    if(FacebookAds)
    {
      let options = {
        adId: '763416880384578_900057893387142'
      };
      FacebookAds.prepareInterstitial(options, function(data){
        FacebookAds.showInterstitial();
      }, function(err){})
    }
  };
}

Make sure to declare FacebookAds variable at the top of home component.

other methods:

FacebookAds.removeBanner();
FacebookAds.showBannerAtXY(x, y);
FacebookAds.hideBanner();

Step 4: Install your Ionic 2 app to your device to test Facebook Audience Network ads

ionic run android -l -c

If you include -l and -c options while installing the project to your device, then you’ll get the live reload and log facility. But you need to be connected to the same network as your terminal where you’re ionic 2 project is running. For Example: Same WiFi for your device as well as your terminal. If your computer is using WiFi and your mobile is using service providers Data connection then this won’t work – in such case use ionic run android command, and you won’t get live reload and log information in the terminal.

Troubleshoot
If you’re getting following errors:
cordova_not_found

OR

int org.json.JSONObject.length() on null

Check these 3 things:
1. You’ve installed proper plugin. Check using ionic plugin list command.
2. You’ve declared FacebookAds variable at the top of the component file.
3. You’ve wrapped the plugins service code inside Platform.ready() method.

If all above 3 conditions are set right, then try this:

Remove platform and add it once again.

ionic platform rm android
ionic platform add android

Now install the project ionic run android -l -c to your device and check.

Important Note: Most Ionic plugins work only on the real devices, so do not try to test it using browsers.

Adding AdMob In Ionic 2

Today lets implement AdMob’s Banner Ads, Interstitial Ads and Rewarded Interstitial or Rewarded Video Ads in our Ionic 2 application.

We’ve installed a blank template for this tutorial

ionic start technotip blank --v2

We create a Ionic 2 project by name ‘technotip’ with blank template.

Related Read: Ionic 2 Starter Templates

Ionic Native
You need to make little changes in plugin installation procedures. Watch Using Ionic Native: Ionic 2 video tutorial to know more.

Implementing AdMob Ads In Ionic 2



YouTube Link: http://www.youtube.com/watch?v=Dj2n_25hcko [Watch the Video In Full Screen.]



Package version information:

C:\ionic2\technotip>ionic info
 
Your system information:
 
Cordova CLI: 6.1.1
Ionic Framework Version: 2.0.0-rc.4
Ionic CLI Version: 2.1.17
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 0.0.47
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v6.7.0
Xcode version: Not installed

Steps To Follow
Step 1: Install AdMobPro plugin
Step 2: Add Platform
Step 3: Implement AdMob into your Ionic 2 project
Step 4: Install your Ionic 2 app to your device to test AdMob ads.

ionic2-admob

Note: Make sure to navigate to your ionic 2 project folder before executing any commands.
Example: Our Ionic 2 project name is ‘technotip’, which is inside a folder called ionic2. So I execute all commands once I get inside

C:\>cd ionic2
C:\ionic2>cd technotip
C:\ionic2\technotip>ionic serve -l -c

Step 1: Install AdMobPro plugin

ionic plugin add cordova-plugin-admobpro

This installs AdMobPro plugin to our Ionic 2 project.

Step 2: Add Platform

ionic platform add android
 
OR
 
ionic platform add ios

If you are developing ios app, then add ios platform(for this, you must be on a Mac). If you’re developing android app, then add android as platform. If you face any difficulty with this step or in installing Ionic framework, please refer to Ionic 2 Starter Templates video tutorial.

Step 3: Implement AdMob into your Ionic 2 project
1. Banner Ads

To show banner ads in all the views of our app, we need to code it inside src/app/app.component.ts

import { AdMob } from 'ionic-native';

Import AdMob Class.

      let options = {
        adId: 'ca-app-pub-5732334124058455/7973166445',
        adSize: 'SMART_BANNER',
        isTesting: false
      };
 
      AdMob.createBanner(options).then(() => {
        AdMob.showBanner(8);
      });

Pass configuration information to createBanner method which returns a promise. After configuring the Banner information call showBanner method and pass the ad position number.

adId – must be AdMob ads banner id.
adSize – Takes following values SMART_BANNER, BANNER, MEDIUM_RECTANGLE, FULL_BANNER, LEADERBOARD, SKYSCRAPER, or CUSTOM. By default it takes the value ‘SMART_BANNER’.
isTesting – Give it true in development and false to show real ads in production.

showBanner method takes a number as parameter.
0 – NO_CHANGE;
1 – TOP_LEFT;
2 – TOP_CENTER;
3 – TOP_RIGHT;
4 – LEFT;
5 – CENTER;
6 – RIGHT;
7 – BOTTOM_LEFT;
8 – BOTTOM_CENTER;
9 – BOTTOM_RIGHT;
10 – POS_XY;

Important Note: If you’re placing any Ionic Native Plugins code inside constructor, then make sure to wrap it around Platform.ready() method orelse it’ll start throwing errors. Since code inside constructor executes as soon as the class is instantiated, the external libraries might not yet have loaded, which causes the code inside constructor to break. If we wrap the code inside platform ready, the code executes only after the device platform is ready.

Full Source Code: src/app/app.component.ts

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen, AdMob } from 'ionic-native';
 
import { HomePage } from '../pages/home/home';
 
 
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage = HomePage;
 
  constructor(platform: Platform) {
    platform.ready().then(() => {
 
      let options = {
        adId: 'ca-app-pub-5732334124058455/7973166445',
        adSize: 'SMART_BANNER',
        isTesting: false
      };
 
      AdMob.createBanner(options).then(() => {
        AdMob.showBanner(8);
      });
 
    });
  }
}

2. Interstitial Ad
We shall invoke an interstitial ad once the user clicks on a button – for demo purpose.

src/pages/home/home.html

  < p>
    < button ion-button (click)="loadAd();">Show Ad< /button>
  < /p>

We’ve added the button to our UI. Once the user clicks on the button, we invoke loadAd() method.

src/pages/home/home.ts

  loadAd(){
   let options = {
    adId: 'ca-app-pub-5732334124058455/3403366048',
    isTesting: false
   };
    AdMob.prepareInterstitial(options)
         .then(() => {
           AdMob.showInterstitial();
         });
  };

we pass interstitial ad units adId to prepareInterstitial() method and then once the promise is returned we invoke showInterstitial() method. We can even pass isTesting option with true or false Boolean value.

Full Source Code: src/pages/home/home.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
 
import { AdMob } from 'ionic-native';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 
  constructor(public navCtrl: NavController) {
 
  }
  loadAd(){
   let options = {
    adId: 'ca-app-pub-5732334124058455/3403366048',
    isTesting: false
   };
    AdMob.prepareInterstitial(options)
         .then(() => {
           AdMob.showInterstitial();
         });
  };
}

Make sure to import ‘AdMob’ at the top of home component.

3. Rewarded Interstitial or Rewarded Video Ad

import { Component } from '@angular/core';
 
import { NavController } from 'ionic-angular';
 
import { AdMob } from 'ionic-native';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 
  constructor(public navCtrl: NavController) {
 
  }
  loadAd(){
   let options = {
    adId: 'ca-app-pub-5732334124058455/7216350441',
    isTesting: false
   };
    AdMob.prepareRewardVideoAd(options)
         .then(() => {
           AdMob.showRewardVideoAd();
         });
  };
}

Pass rewarded interstitial or rewarded video ads adId to prepareRewardVideoAd() method and then invoke showRewardVideoAd() method.

Step 4: Install your Ionic 2 app to your device to test AdMob ads

ionic run android -l -c

If you include -l and -c options while installing the project to your device, then you’ll get the live reload and log facility. But you need to be connected to the same network as your terminal where you’re ionic 2 project is running. For Example: Same WiFi for your device as well as your terminal. If your computer is using WiFi and your mobile is using service providers Data connection then this won’t work – in such case use ionic run android command, and you won’t get live reload and log information in the terminal.

Troubleshoot
If you’re getting following errors:
cordova_not_found

OR

int org.json.JSONObject.length() on null

Check these 3 things:
1. You’ve installed proper plugin. Check using ionic plugin list command.
2. You’ve imported the plugin wherever you’re using its service.
3. You’ve wrapped the plugins service code inside Platform.ready() method.

If all above 3 conditions are set right, then try this:

Remove platform and add it once again.

ionic platform rm android
ionic platform add android

Now install the project ionic run android -l -c to your device and check.

Important Note: Most Ionic Native plugins work only on the real devices, so do not try to test it using browsers.