We have seen series of posts on developing a mobile application using Ionic and AngularJS. One of my previous articles which deal with insertion and deletion of posts using RESTful API. Similarly, today’s post makes use of RESTful API. These days, a single page web applications are most commonly used ones, because of which there is a need to show loads of data on the same page as we keep on scrolling. This infinite scrolling avoids pagination system.
Live Demo
Video Tutorial
Infinite Scrolling using Ionic and Angular with RESTful APIs
Database Design
To build the user social login system, you have to create a user table.
Users
User table contains all the users social details.
CREATE TABLE users(
user_id int AUTO_INCREMENT PRIMARY KEY,
email varchar(300),
name varchar(200),
provider varchar(50),
provider_id varchar(200),
provider_pic varchar(200),
token varchar(500));
user_id int AUTO_INCREMENT PRIMARY KEY,
email varchar(300),
name varchar(200),
provider varchar(50),
provider_id varchar(200),
provider_pic varchar(200),
token varchar(500));
Feed
This table contains user daily updates.
CREATE TABLE feed(
feed_id int PRIMARY KEY AUTO_INCREMENT,
feed text,
user_id_fk int,
created int
);
feed_id int PRIMARY KEY AUTO_INCREMENT,
feed text,
user_id_fk int,
created int
);
home.html
Go to your angular project and include ion-infinite-scroll tag with doInfinite function. This HTML tag will trigger doInfinite function when you reach page scroll down.
<ion-content padding>
</ion-content>
<h2>Welcome to {{userDetails.name}}</h2>
<ion-item id="udpateBox">
<textarea #updatebox [(ngModel)]="userPostData.feed" autofocus></textarea>
<ion-row>
<button ion-button color="energy" (click)="feedUpdate()">Update</button>
</ion-row>
</ion-item>
<ion-card *ngFor="let item of dataSet; let msgIndex = index">
<ion-item>
<ion-icon name="trash" item-right (click)="feedDelete(item.feed_id, msgIndex)"></ion-icon>
<ion-card-content>
<p [innerHTML]="item.feed | linky"></p>
<span>{{this.converTime(item.created) | amTimeAgo}}</span>
</ion-card-content>
</ion-item>
</ion-card>
<ion-infinite-scroll (ionInfinite)="$event.waitFor(doInfinite())">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-infinite-scroll>
home.ts.
In getFeed() function we need to set the last created timestamp for new scroll data. Explained more on video tutorial
import { Component } from "@angular/core";
import { NavController, App, AlertController } from "ionic-angular";
import { AuthService } from "../../providers/auth-service";
import { Common } from "../../providers/common";
@Component({ selector: "page-home", templateUrl: "home.html" })
export class HomePage {
public userDetails: any;
public resposeData: any;
public dataSet: any;
userPostData = {
user_id: "",
token: "",
feed: "",
feed_id: "",
lastCreated: ""
};
constructor(
public common: Common,
private alertCtrl: AlertController,
public navCtrl: NavController,
public app: App,
public authService: AuthService) {
const data = JSON.parse(localStorage.getItem("userData"));
this.userDetails = data.userData;
this.userPostData.user_id = this.userDetails.user_id;
this.userPostData.token = this.userDetails.token;
this.userPostData.lastCreated = "";
this.getFeed();
}
getFeed() {
this.common.presentLoading();
this.authService.postData(this.userPostData, "feed").then(
result => {
this.resposeData = result;
if (this.resposeData.feedData) {
this.common.closeLoading();
this.dataSet = this.resposeData.feedData;
// Data set length
const dataLength = this.resposeData.feedData.length;
const dataLength = this.resposeData.feedData.length;
this.userPostData.lastCreated = this.resposeData.feedData[dataLength - 1].created;
} else {
console.log("No data");
}
},
err => {
//Connection failed message
}
);
}
feedUpdate() {
// API update feed
}
feedDelete(feed_id, msgIndex) {
// API delete feed
}
doInfinite(e): Promise<any> {
console.log("Begin async operation");
return new Promise(resolve => {
setTimeout(() => {
// API Connection for more updates
resolve();
}, 500);
});
}
converTime(time) {
let a = new Date(time * 1000);
return a;
}
backToWelcome() {
const root = this.app.getRootNav();
root.popToRoot();
}
logout() {
//Api Token Logout
localStorage.clear();
setTimeout(() => this.backToWelcome(), 1000);
}
}
Download PHP Restul Project
$git clone https://github.com/srinivastamada/PHP-Slim-Restful.git
PHP RESTful API index.php
Improved feed() function with limited user feed results. If lastCreated is present, we need to get the data based on last timestamp.
<?php
require 'config.php';
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
$app->post('/login','login'); /* User login */
$app->post('/signup','signup'); /* User Signup */
$app->post('/feed','feed'); /* User Feeds */
$app->post('/feedUpdate','feedUpdate'); /* User Feeds */
$app->post('/feedDelete','feedDelete'); /* User Feeds */
//$app->post('/userDetails','userDetails'); /* User Details */
$app->run();
/************************* USER LOGIN *************************************/
/* ### User login ### */
function login() {
// ....
}
/* ### User registration ### */
function signup() {
// ....
}
/* ### internal Username Details ### */
function internalUserDetails($input) {
// ....
}
function feed(){
$request = \Slim\Slim::getInstance()->request();
$data = json_decode($request->getBody());
$user_id=$data->user_id;
$token=$data->token;
$lastCreated = $data->lastCreated;
$systemToken=apiToken($user_id);
try {
if($systemToken == $token){
$feedData = '';
$db = getDB();
if($lastCreated){
$sql = "SELECT * FROM feed WHERE user_id_fk=:user_id AND created < :lastCreated ORDER BY feed_id DESC LIMIT 5";
$stmt = $db->prepare($sql);
$stmt->bindParam("user_id", $user_id, PDO::PARAM_INT);
$stmt->bindParam("lastCreated", $lastCreated, PDO::PARAM_STR);
}
else{
$sql = "SELECT * FROM feed WHERE user_id_fk=:user_id ORDER BY feed_id DESC LIMIT 5";
$stmt = $db->prepare($sql);
$stmt->bindParam("user_id", $user_id, PDO::PARAM_INT);
}
$stmt->execute();
$feedData = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
if{
echo '{"feedData": ' . json_encode($feedData) . '}';
}
else{
echo '{"feedData": ""}';
}
echo '{"feedData": ' . json_encode($feedData) . '}';
}
else{
echo '{"feedData": ""}';
}
} else{
echo '{"error":{"text":"No access"}}';
}
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
function feedUpdate(){
// ...
}
function feedDelete(){
// ...
}
?>
home.ts
Here doInfinite function makes an API call with lastCreated. If the feed response with empty data, it sets the noRecords values as true.
import { Component } from "@angular/core";
import { NavController, App, AlertController } from "ionic-angular";
import { AuthService } from "../../providers/auth-service";
import { Common } from "../../providers/common";
@Component({ selector: "page-home", templateUrl: "home.html" })
export class HomePage {
public userDetails: any;
public resposeData: any;
public dataSet: any;
public noRecords: boolean;
userPostData = {
user_id: "",
token: "",
feed: "",
feed_id: "",
lastCreated: ""
};
constructor(
public common: Common,
private alertCtrl: AlertController,
public navCtrl: NavController,
public app: App,
public authService: AuthService) {
const data = JSON.parse(localStorage.getItem("userData"));
this.userDetails = data.userData;
this.userPostData.user_id = this.userDetails.user_id;
this.userPostData.token = this.userDetails.token;
this.userPostData.lastCreated = "";
this.noRecords = false
this.getFeed();
}
getFeed() {
//...
}
feedUpdate() {
//...
}
feedDelete(feed_id, msgIndex) {
//...
}
doInfinite(e): Promise<any> {
console.log("Begin async operation");
return new Promise(resolve => {
setTimeout(() => {
this.authService.postData(this.userPostData, "feed").then(
result => {
this.resposeData = result;
if (this.resposeData.feedData.length) {
const newData = this.resposeData.feedData;
this.userPostData.lastCreated = this.resposeData.feedData[newData.length - 1].created;
for (let i = 0; i < newData.length; i++) {
this.dataSet.push(newData[i]);
}
} else {
this.noRecords = true;
console.log("No user updates");
}
},
err => {
//Connection failed message
}
);
resolve();
}, 500);
});
}
converTime(time) {
let a = new Date(time * 1000);
return a;
}
backToWelcome() {
//...
}
logout() {
//...
}
}
home.html
Now controlling HTML tag with noRecords values. No records block presents when the noRecords values is true and it stops infinte scrolling action.
<ion-card *ngFor="let item of dataSet; let msgIndex = index">
</ion-infinite-scroll>
<ion-item>
<ion-icon name="trash" item-right (click)="feedDelete(item.feed_id, msgIndex)"></ion-icon>
<ion-card-content>
<p [innerHTML]="item.feed | linky"></p>
<span>{{this.converTime(item.created) | amTimeAgo}}</span>
</ion-card-content>
</ion-item>
</ion-card>
<ion-card *ngIf="noRecords">
<ion-item>
No Records
</ion-item>
</ion-card>
<ion-infinite-scroll (ionInfinite)="$event.waitFor(doInfinite())" *ngIf="!noRecords">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
Which code editing software you used.
ReplyDeleteUncaught SyntaxError: Unexpected token <
ReplyDeleteerror in check demp
1. my feed cant get data if use url api to webserver. but if using localhost xampp my feed can get data
ReplyDelete2. my infinite scroll's not work
is that bug sir? thank you... your tutorial's very usefull
Srinivas i saw in the tutorial that except from these files on Github i have a add other files on XAMPP? Is that to connect the database with the ionic project? Where can i find these files?
ReplyDeletehttps://github.com/srinivastamada/PHP-Slim-Restful
DeleteSrinivas, when i try to simulate i am getting Cannot Find module? I forgot to install somehting?
ReplyDeleteSeverity Code Description Project File Line Suppression State
Error TS2307 Cannot find module '@angular/core'. ionic-restful-authentication-master (tsconfig project) C:\Users\Simon\Cookies\Desktop\Various Scripts\ioniclast\ionic-restful-authentication-master\src\pages\login\login.ts 1 Active
Error Error: Current working directory is not a Cordova-based project. ionicLast1 1
Error TS2307 Cannot find module 'ionic-angular'. ionic-restful-authentication-master (tsconfig project) C:\Users\Simon\Cookies\Desktop\Various Scripts\ioniclast\ionic-restful-authentication-master\src\app\app.component.ts 2 Active
Error TS2307 Cannot find module 'ionic-angular'. ionic-restful-authentication-master (tsconfig project) C:\Users\Simon\Cookies\Desktop\Various Scripts\ioniclast\ionic-restful-authentication-master\src\app\app.module.ts 3
Delete node_modules and platform folders and execute (npm install)
DeleteOK DID THAT. Isn't a Cordova Based project
DeleteSeverity Code Description Project File Line Suppression State
Error Error: Current working directory is not a Cordova-based project. ioniclast 1
Error Adding the Cordova platform failed ioniclast 1
hello Srinivas i followed the steps
Delete$ git clone https://github.com/srinivastamada/ionic-restful-authentication.git
$ cd ionic-restful-authentication
$ npm install
$ ionic serve
All good but how do i make it connect to my phpmyadmin
What should i do? Any tutorial?
Please install XAMPP for PHP APIs.
DeleteSorry Srinivas i meant when you Update something it goes on your Database right? There is not connection to my database
DeleteOn visual studio i did Project>Create Project from existing Files>Apache/Cordova>'Put the folder i downloaded from GitHub', 'Named the Project'>'And then on DEBUG AND SIMULATE'>
ReplyDeleteI am getting an error Procect is not a Cordova based
Try to update your ionic and cordova versions
Delete$ sudo npm install -g ionic cordova
I did i use
Deleteionic 3.18.0
cordova 7.1.0
The PHP restful API is on C:\xampp\htdocs\PHP-Slim-Restful-master
and the Ionic files on C:\Users\Simon\Cookies\Desktop\Various Scripts\ioniclast
what i am doing wrong?
Hello Srinivas i am getting an error: Node Sass does not yet support your current environments: Windows 64-bit with Unsupported runtime(59) What should i do?
Deletesudo npm install --save-dev --unsafe-perm node-sass
DeleteHello Srinivas the project opens on http://localhost:8100/ but i don't know how to open the files on visual studio, on the inspector chrome://devtools/. I have downloaded them when i did git clone https://github.com/srinivastamada/ionic-restful-authentication.git right? How may i did them on visual studio?
ReplyDeleteThanks Srinivas
ReplyDelete
ReplyDeleteI’ve been following your blog from few days.
Your latest post is fantastic and resonated with me. I thought it was something my audience would appreciate,
Thanks