It is recommended to use click event only on clickable elements like button or/and on anchor tags. If you use click event on any other tags(apart from button or anchor tag) there will be some kind of jerkiness or delay of 300 milliseconds.
< ion-list>
< ion-item *ngFor="let Company of companies"
(click)="detailsPage(Company.code);" tappable>
{{Company.name}}
< /ion-item>
< /ion-list>
< ion-list> < ion-item *ngFor="let Company of companies" (click)="detailsPage(Company.code);" tappable> {{Company.name}} < /ion-item> < /ion-list>
Solution Add tapabble attribute if you’re using click event on elements other than button or an anchor tag. In our example we are using click event on ion-item element, so adding tapabble attribute would speed up the firing of click event by 300 milliseconds.
In today’s performance centric application development 300 milliseconds delay shouldn’t be neglected. Hope this small tip helps in improving the usability of your mobile application.
Here we have an array variable(data) which has couple of objects which has company name, product name and an unique code associated with each object. We also have loadAll() method which simply returns this data array variable as promise.
We also have another method called getByDI() which receives an argument. Inside this method, we loop thought the array variable(data) and return the matching id’s object as promise.
src/pages/home/home.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
import { SecondPage } from '../second/second';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
companies: any = 0;
constructor(public navCtrl: NavController, public data: Data) {
this.data.loadAll().then(result => {
this.companies = result;
});
}
detailsPage(id){
this.navCtrl.push(SecondPage, {code: id});
};
}
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
import { SecondPage } from '../second/second';
@Component({ selector: 'page-home', templateUrl: 'home.html'
})
export class HomePage { companies: any = 0; constructor(public navCtrl: NavController, public data: Data) { this.data.loadAll().then(result => { this.companies = result; }); } detailsPage(id){ this.navCtrl.push(SecondPage, {code: id}); };
}
Here we invoke loadAll() method and assign the returned result to companies variable. We also have detailsPage() method which pushes the SecondPage reference to navigation stack and also assigns the value of id to a property called code(we can name this property anything we want). Also note that we have assigned the initial value of companies variable to zero.
Here we show a spinner component until the promise gets resolved. Once the variable companies has some other value than zero, the list items gets displayed. When the user clicks on any of the list item, we invoke detailsPage() method and also pass in its corresponding unique code to the method.
Generating page using Ionic 2 CLI
ionic g page pageName
ionic g page pageName
src/pages/second/second.ts
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({
selector: 'page-second',
templateUrl: 'second.html'
})
export class SecondPage {
company: any = 0;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public data: Data) {
this.data.getByID(this.navParams.get('code')).then(result => {
this.company = result;
});
}
}
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({ selector: 'page-second', templateUrl: 'second.html'
})
export class SecondPage { company: any = 0; constructor(public navCtrl: NavController, public navParams: NavParams, public data: Data) { this.data.getByID(this.navParams.get('code')).then(result => { this.company = result; }); }
}
Here we import NavParams class and using the NavParams reference object and its get method we retrieve the value passed in by the home page to second page. We pass this value to getByID() method and receive details of company which has this unique code as id. Also note that we have assigned zero as initial value to the variable company.
Here we show a spinner component until the promise resolves and the company variable have required results in it.
Important: 1. Make sure to initialize the variables(companies and company variable in our example) and show a spinner or do something with the initial value before trying to access the properties the actual results has – because, if you try to access properties of the result before the promise has resolved, you’ll get errors. For example: In our example, we have name and product properties. If I try to access company.name and company.product before the promise has resolved we’ll get the error – that the name and property of undefined CAN NOT be accessed.
2. Make sure to import all the pages and providers(in our case pages like homepage, second page and Data provider) inside src/app/app.module.ts file and specify the class names and data provider name in appropriate places/blocks/sections as shown in the video tutorial.
Today lets see how we can use ion-spinner components and the animated SVG(Scalable Vector Graphics) it provides.
Using spinner components we can indicate the user that the data is being loaded in the background. This increases the usability and accessibility of the application and enhances the user experience.
Scalable Vector Graphics (SVG) is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation. The SVG specification is an open standard developed by the World Wide Web Consortium (W3C) since 1999. SVG images and their behaviors are defined in XML text files.
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
companies: any = 0;
constructor(public navCtrl: NavController, public data: Data) {
var temp = this;
setTimeout(function(){
temp.data.loadAll().then(result => {
temp.companies = result;
});
}, 3000);
}
}
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({ selector: 'page-home', templateUrl: 'home.html'
})
export class HomePage { companies: any = 0; constructor(public navCtrl: NavController, public data: Data) { var temp = this; setTimeout(function(){ temp.data.loadAll().then(result => { temp.companies = result; }); }, 3000); }
}
Here am using setTimeout method to induce 3 seconds or 3000 milliseconds of delay in assigning return value to the variable companies. Also note that I’ve initialized companies variable to zero.
So there would be a delay of 3 seconds before the data is being loaded. So till then the value of variable companies will be zero. So we use *ngIf directive to show spinner until the value of companies stays zero. When it’s not zero(after 3 seconds) the list items are being displayed and the ion-spinner is removed from the DOM.
Styling – CSS You can change the display property of the spinner using CSS styling.
In this tutorial, I’ll be delaying the display of some list items using setTimeout and setInterval methods of JavaScript and will display the company names(as list items) on the home page.
Here we have an array with couple of objects, which has company name, unique id/code and product details. We also have defined a method loadAll() which returns this.data array as a promise.
src/pages/home/home.html
< ion-list>
< ion-item *ngFor="let Company of companies">
{{Company.name}}
< /ion-item>
< /ion-list>
< ion-list> < ion-item *ngFor="let Company of companies"> {{Company.name}} < /ion-item> < /ion-list>
src/pages/home/home.ts: setInterval
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
companies: any;
constructor(public navCtrl: NavController, public data: Data) {
var temp = this;
var i = 0;
setInterval(function(){ alert('count '+(i++));
temp.data.loadAll().then(result => {
temp.companies = result;
});
}, 3000);
}
}
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({ selector: 'page-home', templateUrl: 'home.html'
})
export class HomePage { companies: any; constructor(public navCtrl: NavController, public data: Data) { var temp = this; var i = 0; setInterval(function(){ alert('count '+(i++)); temp.data.loadAll().then(result => { temp.companies = result; }); }, 3000); }
}
Here we do not use this keyword/variable inside setInterval method, as it would reference to setInterval method and not the HomePage class component. So we take a temporary variable temp outside setInterval method and assign this keyword to it. Now using temp variable we can invoke class component properties and methods.
setinterval method keeps calling itself after every set interval of time. It keeps calling itself until it is stopped using clearInterval() method.
var temp = this;
var i = 0;
var id = setInterval(function(){ alert('count '+(i++));
temp.data.loadAll().then(result => {
temp.companies = result;
});
}, 3000);
clearInterval(id);
var temp = this; var i = 0; var id = setInterval(function(){ alert('count '+(i++)); temp.data.loadAll().then(result => { temp.companies = result; }); }, 3000); clearInterval(id);
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
companies: any;
constructor(public navCtrl: NavController, public data: Data) {
var temp = this;
var i = 0;
setTimeout(function(){
temp.data.loadAll().then(result => {
temp.companies = result;
});
}, 3000);
}
}
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({ selector: 'page-home', templateUrl: 'home.html'
})
export class HomePage { companies: any; constructor(public navCtrl: NavController, public data: Data) { var temp = this; var i = 0; setTimeout(function(){ temp.data.loadAll().then(result => { temp.companies = result; }); }, 3000); }
}
Here setTimeout is executed only once after 3 seconds or 3000 milliseconds. To halt or clear the setTimeout event, we can use clearTimeout() method.
var temp = this;
var i = 0;
var id = setTimeout(function(){
temp.data.loadAll().then(result => {
temp.companies = result;
});
}, 3000);
clearTimeout(id);
var temp = this; var i = 0; var id = setTimeout(function(){ temp.data.loadAll().then(result => { temp.companies = result; }); }, 3000); clearTimeout(id);
Note: Make sure to import the page component and service provider in src/app/app.module.ts file.
Today lets learn about the basics of injectables or providers in Ionic 2. Injectable or provider concept is same as factory or services in Ionic 1 and angular 1.
Injectables are kind of an abstract layer between your application and external or internet data service.
Let us first create a provider by using CLI command
ionic g provider Data
ionic g provider Data
g is a short name for generate Data is our provider name. We can give any name to our provider.
Ionic 2 CLI generates following provider src/providers/data.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class Data {
data: any;
constructor(public http: Http) {
}
}
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class Data {
data: any; constructor(public http: Http) { }
}
We won’t be using Http and map services in this tutorial. We’ll still retain Http reference as we’ll be using it in our next tutorial i.e., passing data between pages using NavParams class.
Here we declare and initiate an array variable( data ) which has couple of objects as its elements. Each object has a company name, a unique code and a product entry. We also define a method called loadAll() which returns the array variable in the form of a promise.
src/pages/home/home.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
companies: any;
constructor(public navCtrl: NavController, public data: Data) {
this.data.loadAll().then(result => {
this.companies = result;
});
}
}
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Data } from '../../providers/data';
@Component({ selector: 'page-home', templateUrl: 'home.html'
})
export class HomePage { companies: any; constructor(public navCtrl: NavController, public data: Data) { this.data.loadAll().then(result => { this.companies = result; }); }
}
Here we import the Data provider and then create its instance/reference. Using this reference we call loadAll() method. Since loadAll() method returns a promise, we use then() to capture the result(once the promise is resolved) and then assign the result to a local variable this.companies