Ionic 2 Mobile App using Angular 2 and TypeScript Tutorial
Ionic is an open-source front-end SDK framework made for building hybrid mobile apps on cross platforms. Ionic is used for developing hybrid mobile apps using web technologies like HTML 5, CSS, Cordova and Sass, it is made of AngularJS 2. Both ionic and AngularJS provides some pre- built in components, which allows us to easily develop mobile apps. Here is the demo for creating mobile app using AngularJS and typescript on ionic V2 framework. The demo used here is my 9lessons.info blog as a mobile app. Follow this tutorial to easily build mobile app.
This Ionic application will explain you, how to parse your blog feed.
Install NodeJS
You need node.js to create a development server, download and install the latest version.
Installing Ionic and Cordova
You will find these instructions in Ionic Framework installation document..
Open your web browser and launch your application at http://localhost:8100.
Now open your project folder with code editors like Atom, Visual Code etc. You will find the following file structure, now we are going work with src folder.
Create New Pages
Now I am going to create two new different pages called Feed and News, go to project folder scr->pages and create folder with empty files in following way
feed.ts
Feed component this is the controller class for displaying blog feed, here imported angular core component and ionic nav controller for page navigations.
feed.html
Ionic standard component tags, you find more about this in Ionic component documentation
Create the same for news.ts and news.html and modify class name and templateUrl.
Modify Tab Controls
Connect news modules to tab controller src->pages->tabs
tabs.ts
to
tabs.ts
Imported FeedPage and NewsPage components.
Go to Ionic icons document, choose your icons.
tabs.html
Replace tabIcon values with new icon names.
to
app.module.ts
You have to import newly created component in app module, go to
src->app->app.module.ts and modify in following way.
Now you will find the new changes
Blog Feed API
My blog is powered by Google blogger. If you launch this following URL, you will find feed API data in JSON format.
http://www.9lessons.info/feeds/posts/default/-/php?max-results=10&alt=json
Note: If you are a Google blogger user, replace www.9lessons.info with your blogspot address.
No Access Control Allow Origin
If you access Google URLs from application, you will get following XMLHttpRequest No 'Access-Control-Allow-Origin' error.
index.php
Code contains PHP curl functionality to access JSON data.
.htaccess
Apache configuration file.
feed.service.ts
This is an angular Injectable component with RxJS and HTTP, you can import this where ever you want to access HTTP request.
I have hosted the phpblogfeed project at demos.9lessons.info, you can access 9lessons.info JSON data at http://demos.9lessons.info/blogfeed/php/10
JSON
app.component.ts
Now modify application main component file and include FeedService in component providers.
feed.ts
Go to src/pages/feed/feed.ts and import FeedService and access getPosts function by passing category and limit values. Service response assigning to articles variable.
ngOnInit function triggers on page load, here I am setting default category and limit values and calling this.getPosts('php', 10)
feed.html
Rendering response data to the HTML template, using angular *ngFor parsing the JSON data.
feed.html
Applying ionic card template
Blogger feed contains HTML tags data, need to filter first image banner and 50 words from feed content.
helper.service.ts
Create a helper injectable component, here getImage() function filtering the first image banner using regular expression. The function getContentSnippet() split the first 50 words.
app.component.ts
Update application main component providers lists with new Helper service.
feed.html
Final Feed.html
Part One Result
This Ionic application will explain you, how to parse your blog feed.
Install NodeJS
You need node.js to create a development server, download and install the latest version.
Installing Ionic and Cordova
You will find these instructions in Ionic Framework installation document..
$ npm install -g cordova ionic
$ ionic start --v2 YourAppName tabs
$ cd YourAppName
$ npm install
$ ionic serve
$ ionic start --v2 YourAppName tabs
$ cd YourAppName
$ npm install
$ ionic serve
Open your web browser and launch your application at http://localhost:8100.
Now open your project folder with code editors like Atom, Visual Code etc. You will find the following file structure, now we are going work with src folder.
Create New Pages
Now I am going to create two new different pages called Feed and News, go to project folder scr->pages and create folder with empty files in following way
feed.ts
Feed component this is the controller class for displaying blog feed, here imported angular core component and ionic nav controller for page navigations.
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
selector: 'page-feed',
templateUrl: 'feed.html'
})
export class FeedPage {
constructor(public navCtrl: NavController) {
}
}
import { NavController } from 'ionic-angular';
@Component({
selector: 'page-feed',
templateUrl: 'feed.html'
})
export class FeedPage {
constructor(public navCtrl: NavController) {
}
}
feed.html
Ionic standard component tags, you find more about this in Ionic component documentation
<ion-header>
<ion-navbar>
<ion-title>Feed Page</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Feed Content Part</h2>
</ion-content>
<ion-navbar>
<ion-title>Feed Page</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Feed Content Part</h2>
</ion-content>
Create the same for news.ts and news.html and modify class name and templateUrl.
Modify Tab Controls
Connect news modules to tab controller src->pages->tabs
tabs.ts
import { Component } from '@angular/core';
import { HomePage } from '../home/home';
import { AboutPage } from '../about/about';
import { ContactPage } from '../contact/contact';
@Component({
templateUrl: 'tabs.html'
})
export class TabsPage {
tab1Root: any = HomePage;
tab2Root: any = AboutPage;
tab3Root: any = ContactPage;
constructor() {
}
}
import { HomePage } from '../home/home';
import { AboutPage } from '../about/about';
import { ContactPage } from '../contact/contact';
@Component({
templateUrl: 'tabs.html'
})
export class TabsPage {
tab1Root: any = HomePage;
tab2Root: any = AboutPage;
tab3Root: any = ContactPage;
constructor() {
}
}
to
tabs.ts
Imported FeedPage and NewsPage components.
import { Component } from '@angular/core';
import { FeedPage } from '../feed/feed';
import { NewsPage } from '../news/news';
import { AboutPage } from '../about/about';
@Component({
templateUrl: 'tabs.html'
})
export class TabsPage {
tab1Root: any = FeedPage;
tab2Root: any = NewsPage;
tab3Root: any = AboutPage;
constructor() {
}
}
import { FeedPage } from '../feed/feed';
import { NewsPage } from '../news/news';
import { AboutPage } from '../about/about';
@Component({
templateUrl: 'tabs.html'
})
export class TabsPage {
tab1Root: any = FeedPage;
tab2Root: any = NewsPage;
tab3Root: any = AboutPage;
constructor() {
}
}
Go to Ionic icons document, choose your icons.
tabs.html
Replace tabIcon values with new icon names.
<ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="About" tabIcon="about"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts"></ion-tab>
</ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="About" tabIcon="about"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts"></ion-tab>
</ion-tabs>
to
<ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Feed" tabIcon="egg"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="News" tabIcon="paper"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="About" tabIcon="contact"></ion-tab>
</ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Feed" tabIcon="egg"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="News" tabIcon="paper"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="About" tabIcon="contact"></ion-tab>
</ion-tabs>
app.module.ts
You have to import newly created component in app module, go to
src->app->app.module.ts and modify in following way.
import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { AboutPage } from '../pages/about/about';
import { NewsPage } from '../pages/news/news';
import { FeedPage } from '../pages/feed/feed';
import { TabsPage } from '../pages/tabs/tabs';
@NgModule({
declarations: [
MyApp,
AboutPage,
NewsPage,
FeedPage,
TabsPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
AboutPage,
NewsPage,
FeedPage,
TabsPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { AboutPage } from '../pages/about/about';
import { NewsPage } from '../pages/news/news';
import { FeedPage } from '../pages/feed/feed';
import { TabsPage } from '../pages/tabs/tabs';
@NgModule({
declarations: [
MyApp,
AboutPage,
NewsPage,
FeedPage,
TabsPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
AboutPage,
NewsPage,
FeedPage,
TabsPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}
Now you will find the new changes
Blog Feed API
My blog is powered by Google blogger. If you launch this following URL, you will find feed API data in JSON format.
http://www.9lessons.info/feeds/posts/default/-/php?max-results=10&alt=json
Note: If you are a Google blogger user, replace www.9lessons.info with your blogspot address.
No Access Control Allow Origin
If you access Google URLs from application, you will get following XMLHttpRequest No 'Access-Control-Allow-Origin' error.
PHP Blog Feed
CURL access to allow X-Frame-Options using .htaccess. index.php
Code contains PHP curl functionality to access JSON data.
<?php
if($_GET['category'] && $_GET['limit']){
$category = $_GET['category'];
$limit = $_GET['limit'];
$url ="http://www.9lessons.info/feeds/posts/default/-/".$tag."?max-results=".$limit."&alt=json";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 12);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close ($ch);
echo $result;
}
?>
if($_GET['category'] && $_GET['limit']){
$category = $_GET['category'];
$limit = $_GET['limit'];
$url ="http://www.9lessons.info/feeds/posts/default/-/".$tag."?max-results=".$limit."&alt=json";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 12);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close ($ch);
echo $result;
}
?>
.htaccess
Apache configuration file.
RewriteEngine On
Header always unset X-Frame-Options
RewriteRule ^([a-zA-Z0-9_%-]+)$ index.php?category=$1
RewriteRule ^([a-zA-Z0-9_%-]+)/$ index.php? category =$1
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)$ index.php?category =$1&limit=$2
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)/$ index.php?category =$1&limit=$2
Header always unset X-Frame-Options
RewriteRule ^([a-zA-Z0-9_%-]+)$ index.php?category=$1
RewriteRule ^([a-zA-Z0-9_%-]+)/$ index.php? category =$1
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)$ index.php?category =$1&limit=$2
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)/$ index.php?category =$1&limit=$2
Create a feed HTTP Ajax service
Create a services folder in scr->appfeed.service.ts
This is an angular Injectable component with RxJS and HTTP, you can import this where ever you want to access HTTP request.
import { Injectable } from "@angular/core";
import { Http } from '@angular/http';
import 'rxjs/Rx';
@Injectable()
export class FeedService {
http: any;
feedURL: String;
constructor(http: Http) {
this.http = http;
this.feedURL = 'http://demos.9lessons.info/blogfeed/';
}
getPosts(category, limit) {
return this.http.get(this.feedURL + category + '/' + limit).map(res => res.json());
}
}
import { Http } from '@angular/http';
import 'rxjs/Rx';
@Injectable()
export class FeedService {
http: any;
feedURL: String;
constructor(http: Http) {
this.http = http;
this.feedURL = 'http://demos.9lessons.info/blogfeed/';
}
getPosts(category, limit) {
return this.http.get(this.feedURL + category + '/' + limit).map(res => res.json());
}
}
I have hosted the phpblogfeed project at demos.9lessons.info, you can access 9lessons.info JSON data at http://demos.9lessons.info/blogfeed/php/10
JSON
app.component.ts
Now modify application main component file and include FeedService in component providers.
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { FeedService } from './services/feed.service';
import { TabsPage } from '../pages/tabs/tabs';
@Component({
templateUrl: 'app.html',
providers: [FeedService]
})
export class MyApp {
rootPage = TabsPage;
constructor(platform: Platform) {
platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
});
}
}
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { FeedService } from './services/feed.service';
import { TabsPage } from '../pages/tabs/tabs';
@Component({
templateUrl: 'app.html',
providers: [FeedService]
})
export class MyApp {
rootPage = TabsPage;
constructor(platform: Platform) {
platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
});
}
}
Using Feed Service
Importing FeedService component into feed page. feed.ts
Go to src/pages/feed/feed.ts and import FeedService and access getPosts function by passing category and limit values. Service response assigning to articles variable.
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { FeedService } from '../../app/services/feed.service';
@Component({
selector: 'page-feed',
templateUrl: 'feed.html'
})
export class FeedPage {
articles: any;
category: any;
limit: any;
constructor(public navCtrl: NavController, private feedService: FeedService) {
}
ngOnInit() {
this.getPosts('php', 10);
}
getPosts(category,limit){
this.feedService.getPosts(category, limit).subscribe(response => {
console.log(response.responseData.feed.entries); // Blog Data
this.articles = response.responseData.feed.entries;
})
}
}
import { NavController } from 'ionic-angular';
import { FeedService } from '../../app/services/feed.service';
@Component({
selector: 'page-feed',
templateUrl: 'feed.html'
})
export class FeedPage {
articles: any;
category: any;
limit: any;
constructor(public navCtrl: NavController, private feedService: FeedService) {
}
ngOnInit() {
this.getPosts('php', 10);
}
getPosts(category,limit){
this.feedService.getPosts(category, limit).subscribe(response => {
console.log(response.responseData.feed.entries); // Blog Data
this.articles = response.responseData.feed.entries;
})
}
}
ngOnInit function triggers on page load, here I am setting default category and limit values and calling this.getPosts('php', 10)
feed.html
Rendering response data to the HTML template, using angular *ngFor parsing the JSON data.
<ion-header>
<ion-navbar>
<ion-title>Feed Page</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Feed Page</h2>
<div *ngFor="let article of articles">
<div>{{article.title.$t}}</div>
</div>
</ion-content>
<ion-navbar>
<ion-title>Feed Page</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Feed Page</h2>
<div *ngFor="let article of articles">
<div>{{article.title.$t}}</div>
</div>
</ion-content>
feed.html
Applying ionic card template
<ion-card *ngFor="let article of articles">
<ion-item class="item-text-wrap">
<h2 class="wrap">{{article.title}}</h2>
</ion-item>
<ion-card-content>
<p [innerHTML]="article.content.$t">
</p>
<div class="date">{{article.published.$t | date}}</div>
</ion-card-content>
<--- Tags HTML --- >
<ion-row>
<ion-col>
<a class="tag" *ngFor="let tag of article.category" >
{{tag.term}}
</a>
</ion-col>
</ion-row>
</ion-card>
<ion-item class="item-text-wrap">
<h2 class="wrap">{{article.title}}</h2>
</ion-item>
<ion-card-content>
<p [innerHTML]="article.content.$t">
</p>
<div class="date">{{article.published.$t | date}}</div>
</ion-card-content>
<--- Tags HTML --- >
<ion-row>
<ion-col>
<a class="tag" *ngFor="let tag of article.category" >
{{tag.term}}
</a>
</ion-col>
</ion-row>
</ion-card>
Blogger feed contains HTML tags data, need to filter first image banner and 50 words from feed content.
helper.service.ts
Create a helper injectable component, here getImage() function filtering the first image banner using regular expression. The function getContentSnippet() split the first 50 words.
import { Injectable } from "@angular/core";
@Injectable()
export class Helper {
constructor() {
}
getImage(content) {
var myRegexp = new RegExp(/<img.*?src="(.*?)"/);
var match = myRegexp.exec(content);
if (match){
return match[1];
}
}
getContentSnippet(str) {
return str.split(/\s+/).slice(0, 50).join(" ")+"...";
}
}
@Injectable()
export class Helper {
constructor() {
}
getImage(content) {
var myRegexp = new RegExp(/<img.*?src="(.*?)"/);
var match = myRegexp.exec(content);
if (match){
return match[1];
}
}
getContentSnippet(str) {
return str.split(/\s+/).slice(0, 50).join(" ")+"...";
}
}
app.component.ts
Update application main component providers lists with new Helper service.
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { FeedService } from './services/feed.service';
import { Helper } from './services/helper.service';
import { TabsPage } from '../pages/tabs/tabs';
@Component({
templateUrl: 'app.html',
providers: [FeedService, Helper]
})
export class MyApp {
rootPage = TabsPage;
constructor(platform: Platform) {
platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
});
}
}
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { FeedService } from './services/feed.service';
import { Helper } from './services/helper.service';
import { TabsPage } from '../pages/tabs/tabs';
@Component({
templateUrl: 'app.html',
providers: [FeedService, Helper]
})
export class MyApp {
rootPage = TabsPage;
constructor(platform: Platform) {
platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
});
}
}
feed.html
Final Feed.html
<ion-header>
<ion-navbar>
<ion-title>Feed Page</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-card *ngFor="let article of articles">
<ion-item class="item-text-wrap">
<h2 class="wrap">{{article.title}}</h2>
</ion-item>
<img src="{{getImage(article.content)}}" *ngIf="getImage(article.content)">
<ion-card-content>
<p [innerHTML]="getContentSnippet(article.content.$t)">
</p>
<div class="date">{{article.publishedDate | date}}</div>
</ion-card-content>
<--- Tags HTML --- >
<ion-row>
<ion-col>
<a class="tag" *ngFor="let tag of article.categories" >
{{tag.term}}
</a>
</ion-col>
</ion-row>
</ion-card>
</ion-content>
<ion-navbar>
<ion-title>Feed Page</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-card *ngFor="let article of articles">
<ion-item class="item-text-wrap">
<h2 class="wrap">{{article.title}}</h2>
</ion-item>
<img src="{{getImage(article.content)}}" *ngIf="getImage(article.content)">
<ion-card-content>
<p [innerHTML]="getContentSnippet(article.content.$t)">
</p>
<div class="date">{{article.publishedDate | date}}</div>
</ion-card-content>
<--- Tags HTML --- >
<ion-row>
<ion-col>
<a class="tag" *ngFor="let tag of article.categories" >
{{tag.term}}
</a>
</ion-col>
</ion-row>
</ion-card>
</ion-content>
Part One Result
No comments:
Write comments