I am trying to achieve a log out functionality. I am using FB authentication. My problem here is after I do a logout successfully(This happens from the Side menu ) I return to the Login Screen. But now if I tap the device's back button it is taking me to the homepage(. Any idea how to prevent this ?
This is my app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Platform, Nav, AlertController } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { LoginPage } from '../pages/login/login';
import { NativeStorage } from '#ionic-native/native-storage';
import { TabsPage } from '../pages/tabs/tabs';
import { Facebook } from 'ionic-native';
#Component({
templateUrl: 'app.html',
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage: any = LoginPage;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, private nativeStorage: NativeStorage, private alertCtrl: AlertController) {
platform.ready().then(() => platform.ready().then(() => {
this.nativeStorage.getItem("userId").then((data) => {
console.log(data.userExists);
this.rootPage = TabsPage;
this.nav.push(TabsPage);
}, (error) => {
console.log("No data in storage");
this.nav.push(LoginPage);
})
statusBar.styleDefault();
splashScreen.hide();
})
)
}
presentConfirm() {
let alert = this.alertCtrl.create({
title: "Confirm Logout",
message: "Do you really really want to quit this awesome app?",
buttons: [{
text: 'Nah! Just Kidding!', role: 'cancel', handler: () => {
}
},
{
text: "Ok",
handler: () => {
this.nativeStorage.clear();
this.nav.push(LoginPage);
this.rootPage = LoginPage;
Facebook.logout().then((response) => {
}, (error) => {
})
}
}]
});
alert.present();
}
}
This is my login page. Login.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Facebook } from 'ionic-native';
import { NativeStorage } from '#ionic-native/native-storage';
import { TabsPage } from '../tabs/tabs'
#Component({
selector: 'login-home',
templateUrl: 'login.html'
})
export class LoginPage {
constructor(public navCtrl: NavController, private nativeStorage: NativeStorage) {
}
FBLogin() {
//this.navCtrl.push(TabsPage); - To be used on browser environment
Facebook.login(['email']).then((response) => {
Facebook.getLoginStatus().then((response) => {
if (response.status == 'connected') {
this.navCtrl.push(TabsPage); // - to be used on device
console.log("Setting Storage")
this.nativeStorage.setItem("userId", { userExists: true });
Facebook.api('/' + response.authResponse.userID + '?fields=id,name,gender', []).then((response) => {
}, (error) => {
alert(error)
})
}
else
alert("Not Logged in");
})
}, (error) => {
console.log((error));
})
}
}
This is my Menu
<ion-menu swipeEnabled="false" side="right" [content]="content">
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<p> </p>
<button menuClose padding-top ion-item> Test 1 </button>
<button menuClose ion-item> Test 2 </button>
<button menuClose ion-item (click)="presentConfirm()"><ion-icon name="power"></ion-icon> Logout </button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav id="nav" [root]="rootPage" #content swipe-back-enabled="false"></ion-nav>
Your issue is you are doing:
this.nav.push(LoginPage);
in your logout handler.
This means LoginPage is added on top of your old navigation stack. You need to set a new stack and set LoginPage as root.
Do :
this.nav.setRoot(LoginPage);
Related
I have implemented a side-menu in Ionic2.I am getting "Invalid link" when i click on the Event or Map button on the side-menu and sometimes i get the error as "Invalid Views to insert". I tried removing quotes from the calendar and gmap but it does not work out.
Please guide.
This is my TS file:
import { Component } from '#angular/core';
import { Platform , IonicPage } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { CalendarPage } from '../pages/calendar/calendar'
import { GmapPage } from '../pages/gmap/gmap'
import firebase from 'firebase';
import { LoginPage } from '../pages/login/login';
import { ViewChild } from '#angular/core';
import { NavController } from 'ionic-angular/navigation/nav-controller';
import { AuthProvider } from '../providers/auth/auth';
#IonicPage()
#Component({
templateUrl: 'app.html'
})
export class MyApp {
calendar: CalendarPage;
gmap: GmapPage;
#ViewChild('nav') nav: NavController;
rootPage: any = CalendarPage;
pages = []
constructor(platform: Platform, statusBar: StatusBar, splashScreen:SplashScreen,
public authProvider: AuthProvider) {
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.
statusBar.styleDefault();
splashScreen.hide();
const unsubscribe = firebase.auth().onAuthStateChanged(user => {
if (!user) {
this.rootPage = 'LoginPage';
unsubscribe();
} else {
this.rootPage = 'EventPage';
unsubscribe();
}
});
});
}
onLoad(page : string) {
this.nav.setRoot(page);
}
onLogout(){
this.authProvider.logoutUser();
}
}
This is my HTML code :
<ion-menu [content] = "nav">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button ion-item (click) = "onLoad('calendar')">Events</button>
<button ion-item (click) = "onLoad('gmap')">Maps</button>
<button ion-item (click) = "onLogout()">Logout</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav [root]="rootPage" #nav></ion-nav>
How to add sub-menu in ion sidemenu? I have done following code for side menu
app.html
<ion-menu [content]="content">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
app.compact.ts
import { Component ,ViewChild} from '#angular/core';
import { Platform ,Nav} from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { Dashboard } from '../pages/dashboard/dashboard';
import { LineBoy } from '../pages/line-boy/line-boy';
import { Customer } from '../pages/customer/customer';
import { DeliveryLine } from '../pages/delivery-line/delivery-line';
import { Newspaper } from '../pages/newspaper/newspaper';
import { Scheme } from '../pages/scheme/scheme';
import { Expenses } from '../pages/expenses/expenses';
import { Report } from '../pages/report/report';
import { Billing } from '../pages/billing/billing';
import { Settings }from '../pages/settings/settings';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = Dashboard;
#ViewChild(Nav) nav: Nav;
pages: Array<{title: string, component: any}>;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
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.
statusBar.styleDefault();
splashScreen.hide();
});
this.pages = [
{ title: 'Dashboard', component: Dashboard },
{ title: 'LineBoy', component: LineBoy },
{ title: 'DeliveryLine', component: DeliveryLine },
{ title: 'Customer', component: Customer },
{ title: 'Newspaper', component: Newspaper },
{ title: 'Scheme', component: Scheme },
{ title: 'Expenses', component: Expenses },
{ title: 'Report', component: Report },
{ title: 'Billing', component: Billing },
{ title: 'Settings', component: Settings },
];
}
openPage(page) {
this.nav.setRoot(page.component);
}
}
https://market.ionic.io/plugins/ionic-multilevel-sidemenu
I have an ionic 2 app and am using native FB Login to retrieve name/pic and saving it to NativeStorage. The flow is that I open WelcomePage, log in, and save the data. From there, navPush to HomePage. So far it works great.
However, I have a ProfilePage (accessible via tabRoot), the fails. The reason is that in my profile.html I have the following tag that should render Username (this works on HomePage, but not on ProfilePage):
{{ user.name }}
The error I get on XCode is:
2017-05-02 18:40:41.657374 FoxBox App[1102:226159] ERROR: Failed to navigate: undefined is not an object (evaluating 'co.user.picture')
Note that for some reason it prepends it with 'co.' which I have no idea where its coming from or what it means.
Here is the WelcomePage code:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { HomePage } from '../home/home';
import { AboutPage } from '../about/about';
import { Facebook, NativeStorage } from 'ionic-native';
//import { FacebookAuth, User, Auth } from '#ionic/cloud-angular';
import { CloudSettings, CloudModule } from '#ionic/cloud-angular';
import {GoogleAnalytics} from 'ionic-native';
#Component({
selector: 'page-welcome',
templateUrl: 'welcome.html'
})
export class WelcomePage {
FB_APP_ID: number = 1234567890;
homePage = HomePage;
aboutPage = AboutPage;
constructor(
public navCtrl: NavController,
//public facebookAuth: FacebookAuth,
//public auth: Auth,
//public user: User,
) {
Facebook.browserInit(this.FB_APP_ID, "v2.8");
}
doFbLogin(){
//alert("fb is logged in");
let permissions = new Array();
let nav = this.navCtrl;
//the permissions your facebook app needs from the user
permissions = ["public_profile"];
Facebook.login(permissions)
.then(function(response){
let userId = response.authResponse.userID;
let params = new Array();
//Getting name and gender properties
Facebook.api("/me?fields=name,gender", params)
.then(function(user) {
user.picture = "https://graph.facebook.com/" + userId + "/picture?type=large";
//now we have the users info, let's save it in the NativeStorage
NativeStorage.setItem('user',
{
name: user.name,
gender: user.gender,
picture: user.picture,
email: user.email,
})
.then(function(){
nav.push(HomePage);
console.log("User Data Stored");
}, function (error) {
console.log(error);
})
})
}, function(error){
console.log(error);
});
}
}
Here is the HomePage code:
import { Component } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
import { ClaimPage } from '../claim/claim';
import { SocialSharing } from '#ionic-native/social-sharing';
import { Facebook, NativeStorage } from 'ionic-native';
//import { FacebookAuth, User, Auth } from '#ionic/cloud-angular';
import { CloudSettings, CloudModule } from '#ionic/cloud-angular';
import {GoogleAnalytics} from 'ionic-native';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
posts: any;
sendme: any;
claimPage = ClaimPage;
user: any;
userReady: boolean = false;
constructor(
public navCtrl: NavController,
public http: Http,
private sharingVar: SocialSharing,
public platform: Platform,
) {
// Check to see if user already exists (via FB login)
let env = this;
NativeStorage.getItem('user')
.then(function (data){
env.user = {
name: data.name,
gender: data.gender,
picture: data.picture
};
env.userReady = true;
// console.log(data.name);
}, function(error){
console.log(error);
});
this.platform.ready().then(() => {
//alert("platform is ready");
GoogleAnalytics.trackView("Home-Page", "http://foxboxapp.com/home", true);
//alert("GA called");
});
this.http.get('http://getyourtryston.com/foox/sample.php').map(res => res.json()).subscribe(data => {
this.posts = data.data.children;
});
}
otherShare(){
this.sharingVar.share("FoxBox App","Get Awesome College Deals",null/*File*/,"http://fooxsocial.com")
.then(()=>{
//alert("Success");
},
()=>{
alert("Sharing Failed!")
})
}
}
And here is the ProfilePage code which fails:
import { Component } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import { WelcomePage } from '../welcome/welcome';
import {GoogleAnalytics} from 'ionic-native';
import { SocialSharing } from '#ionic-native/social-sharing';
import { Facebook, NativeStorage } from 'ionic-native';
//import { FacebookAuth, User, Auth } from '#ionic/cloud-angular';
//import { CloudSettings, CloudModule } from '#ionic/cloud-angular';
#Component({
selector: 'page-about',
templateUrl: 'about.html'
})
export class AboutPage {
user: any;
userReady: boolean = false;
constructor(
public navCtrl: NavController,
public platform: Platform,
private sharingVar: SocialSharing,
//public facebookAuth:FacebookAuth,
//public auth:Auth,
) {
// Check to see if user already exists (via FB login)
let env = this;
NativeStorage.getItem('user')
.then(function (data){
env.user = {
name: data.name,
gender: data.gender,
picture: data.picture
};
env.userReady = true;
// console.log(data.name);
}, function(error){
console.log(error);
});
// PLATFORM READY, do your thang!
this.platform.ready().then(() => {
// Ping Google Analytics
GoogleAnalytics.trackView("Profile Page", "http://foxboxapp.com/home", true);
});
}
otherShare(){
this.sharingVar.share("FOOX Social App","Get Awesome College Deals",null/*File*/,"http://fooxsocial.com")
.then(()=>{
//alert("Success");
},
()=>{
alert("Sharing Failed!")
})
}
doFbLogout(){
var nav = this.navCtrl;
Facebook.logout()
.then(function(response) {
//user logged out so we will remove him from the NativeStorage
NativeStorage.remove('user');
nav.push(WelcomePage);
}, function(error){
console.log(error);
});
}
}
And here is ProfilePage.html
<ion-header>
<ion-navbar color="light" hideBackButton="true">
<ion-buttons end>
<button ion-button icon-only (click)="otherShare()">
<ion-icon name="share"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<ion-card class="pCard">
<div class="pHeader" align="center">
<div *ngIf="user" class="pImgBox" align="center">
<img class="pImage" src="{{ user.picture }}">
</div>
<div class="pUsername" align="center">
<div *ngIf="user"> {{user.name}} </div>
<br>
<span class="pSchool">(Santa Monica College)</span>
</div>
</div>
<ion-list>
<ion-item class="pItems">
Share App
</ion-item>
<ion-item class="pItems">
Give Us Feedback
</ion-item>
<ion-item class="pItems">
Suggest Vendors
</ion-item>
<ion-item class="pItems">
Privacy & Terms of Service
</ion-item>
<ion-item class="pItems">
Log Out
</ion-item>
<ion-item class="pItems">
Delete Account
</ion-item>
</ion-list>
</ion-card>
<button ion-button round (click)="doFbLogout()">Log Out</button>
</ion-content>
I should mention that, if I remove {{ user.name }} and {{ user.picture }} from my ProfilePage.html, there does NOT seem to be any problems. In fact, if you notice in the ts of ProfilePage, I can both Alert and Console.log the username (data.name) without any issues.
I'm a beginner and would appreciate any concise help in this regard. Thank you.
I finally found a solution. In the html file (ProfilePage.html), I used an *ngIf conditional:
<div *ngIf="user"> {{user.name}} </div>
This will introduce a delay such that the 'user' object is no longer null as it reads from NativeStorage.
Alternatively, an Elvis Operator also works for me:
<div> {{ user?.name }} </div>
I am in the process of upgrading from Ionic 2 beta to Ionic 2 rc3.
I have my app.component.ts file, that worked fine, when it was just displaying a root page. But as soon as I have tried to add menu items from my old working Ionic 2 beta version, I get the error below.
If anyone can advise how I can resolve this, I would appreciate the help.
Compile Error in CLI
[13:14:56] template error, "E:\Development\IDE\ionic-apps\WhatsAppClone\src\app\build\app.html": Error: ENOENT: no such
file or directory, open 'E:\Development\IDE\ionic-apps\WhatsAppClone\src\app\build\app.html'
Runtime Error in browser console
Unhandled Promise rejection: Failed to load build/app.html ; Zone: meteor-rxjs-zone ; Task: Promise.then ; Value: Failed to load build/app.html undefined polyfills.js:3:7730
Error: Uncaught (in promise): Failed to load build/app.html
Stack trace:
s#http://localhost:8100/build/polyfills.js:3:8568
s#http://localhost:8100/build/polyfills.js:3:8391
h/<#http://localhost:8100/build/polyfills.js:3:8902
sg</d</t.prototype.invokeTask#http://localhost:8100/build/polyfills.js:3:14040
sg</v</e.prototype.runTask#http://localhost:8100/build/polyfills.js:3:11392
i#http://localhost:8100/build/polyfills.js:3:8021
t/this.invoke#http://localhost:8100/build/polyfills.js:3:15204
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Storage } from "#ionic/storage";
import { Platform, Events, AlertController, Nav } from 'ionic-angular';
import { StatusBar, Push, Splashscreen } from 'ionic-native';
import { SearchJobsPage } from "../pages/searchjobs/searchjobs";
import { LoginPage } from '../pages/login/login';
import { LogoutPage } from '../pages/logout/logout';
import { PersonModel } from '../pages/model/personModel';
import { ChatsPage } from '../pages/chats/chats';
import { PersonPage } from '../pages/person/person';
import { SearchFavouriteJobsPage } from '../pages/searchfavouritejobs/searchfavouritejobs';
import { SearchPostingsPage } from '../pages/searchpostings/searchpostings';
import { SearchFavouritePostingsPage } from '../pages/searchfavouritepostings/searchfavouritepostings';
import { UtilityService } from '../pages/utils/utilityService';
import { NotificationService } from '../pages/service/notificationService';
import { JobService } from '../pages/service/jobService';
import { JobModel } from '../pages/model/jobModel';
import { MapLocationsPage } from '../pages/maplocations/maplocations';
import { MapRangePage } from '../pages/maprange/maprange';
//import { METEOR_PROVIDERS } from 'angular2-meteor';
// import * as Check from 'meteor/check';
// import * as EJSON from 'meteor/ejson';
//declare let Meteor;
#Component({
templateUrl: 'build/app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage: any;
public storage: Storage = null;
public pages: Array<{ title: string, component: any }>;
public pages_person: Array<{ title: string, component: any }>;
public pages_person_admin: Array<{ title: string, component: any }>;
public menuTitle: string = 'Menu';
public personModel: PersonModel = null;
public utilityService: UtilityService = null;
public notificationService: NotificationService = null;
public personModelLoggedIn: PersonModel;
public jobService: JobService = null;
public events: Events = null;
public ios: boolean = false;
constructor(private platform: Platform, utilityService: UtilityService, notificationService: NotificationService, jobService: JobService, events: Events, private alertCtrl: AlertController, storage: Storage) {
this.storage = storage;
this.utilityService = utilityService;
this.jobService = jobService;
this.notificationService = notificationService;
this.events = events;
this.initializeApp();
if (this.platform.is('ios')) {
this.ios = true;
}
// this.rootPage = Meteor.user() ? TabsPage : LoginComponent;
this.rootPage = SearchJobsPage;
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.initializeApp();
StatusBar.styleDefault();
Splashscreen.hide();
});
// used for an example of ngFor and navigation
this.pages = [
{ title: 'Market', component: SearchJobsPage },
{ title: 'Postings', component: SearchPostingsPage },
{ title: 'Login', component: LoginPage }
];
this.pages_person = [
{ title: 'Market', component: SearchJobsPage },
{ title: 'Market Favourites', component: SearchFavouriteJobsPage },
{ title: 'Postings', component: SearchPostingsPage },
{ title: 'Favourite Postings', component: SearchFavouritePostingsPage },
{ title: 'Messages', component: ChatsPage },
{ title: 'Profile', component: PersonPage },
{ title: 'Logout', component: LogoutPage }
];
this.pages_person_admin = [
{ title: 'Market', component: SearchJobsPage },
{ title: 'Market Favourites', component: SearchFavouriteJobsPage },
{ title: 'Postings', component: SearchPostingsPage },
{ title: 'Favourite Postings', component: SearchFavouritePostingsPage },
{ title: 'Messages', component: ChatsPage },
{ title: 'Profile', component: PersonPage },
{ title: 'Logout', component: LogoutPage },
{ title: 'Map Locations', component: MapLocationsPage },
{ title: 'Map Range', component: MapRangePage }
];
}
initializeApp() {
StatusBar.styleDefault();
this.checkLogin();
this.utilityService.startUpChecks();
if (window['cordova']) {
this.utilityService.setLocalStrorage('this.chats.observe', 'false');
this.utilityService.setLocalStrorage('this.messages.observe', 'false');
this.utilityService.setLocalStrorage('this.messages.subscribe', 'false');
this.utilityService.setLocalStrorage('push:notifications.subscribe', 'false');
}
this.subscribeEvents();
}
// openPage(page) {
// // Reset the content nav to have just this page
// // we wouldn't want the back button to show in this scenario
// this.nav.setRoot(page.component);
// }
public subscribeEvents(): void {
this.events.subscribe('push:notifications', (data) => {
this.checkLogin();
});
}
public pushNotifications(): void {
let observedPromise: Promise<string> = this.utilityService.getLocalStrorage('push:notifications.subscribe');
observedPromise.then((observed: string) => {
if (!observed || observed != 'true') {
this.utilityService.setLocalStrorage('push:notifications.subscribe', 'true');
try {
if (window['cordova']) {
if (this.personModelLoggedIn) {
let promiseJobsForPerson: Promise<JobModel[]> = this.jobService.getJobsByPerson(this.personModelLoggedIn.id);
promiseJobsForPerson.then((data) => {
let jobModelsForPerson: JobModel[] = data;
let topics: string[] = [];
topics.push('P' + this.personModelLoggedIn.id);
for (let i = 0; i < jobModelsForPerson.length; i++) {
let jobModel: JobModel = jobModelsForPerson[i];
topics.push('J' + jobModel.id);
}
//topics.push('J65'); // deleteme
//topics.push('P9'); // deleteme
let push = Push.init({
android: {
senderID: "893141127008",
topics: topics
},
ios: {
alert: "true",
badge: false,
sound: "true",
topics: topics
},
windows: {}
});
push.on('registration', (data1) => {
this.events.subscribe('messages:notify', (data) => {
let promise: Promise<string> = this.notificationService.push('null', data[0].topic, data[0].message, data[0].title);
promise.then((data2) => {
// console.log('app.ts messages2:notify', data2);
});
});
});
push.on('notification', (data) => {
this.events.publish('messages:update');
if (this.nav.getActive().name != 'ChatsPage' && this.nav.getActive().name != 'MessagesPage') {
//if user using app and push notification comes
if (data.additionalData.foreground) {
//if application open, show popup
let confirmAlert = this.alertCtrl.create({
title: data.title,
message: data.message,
buttons: [{
text: 'Ignore',
role: 'cancel'
}, {
text: 'View',
handler: () => {
this.rootPage = ChatsPage;
}
}]
});
confirmAlert.present(confirmAlert);
} else {
this.rootPage = ChatsPage;
}
}
});
push.on('error', (e) => {
alert('Error: ' + e.message);
console.log(e);
});
});
}
}
} catch (e) {
alert('Push Notification: ' + e.message());
console.log('Push Notification: ' + e.message());
}
}
});
}
public checkLogin(): void {
let promise: Promise<string> = this.utilityService.getLoggedInPerson();
promise.then((data) => {
this.personModelLoggedIn = JSON.parse(data);
if (this.personModelLoggedIn) {
this.utilityService.setUpMenuItems();
this.pushNotifications();
}
});
}
}
app.html
<ion-menu [content]="content" id="unauthenticated">
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-menu [content]="content" id="authenticated-person">
<ion-toolbar [class]="ios ? 'menu-toolbar' : ''">
<ion-title [class]="ios ? 'menu-title' : ''">
<div class="item-avatar-img" id="menu-item-avatar-img-person"></div>
<div class="item-avatar-name" id="menu-item-avatar-name-person"></div>
</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages_person" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-menu [content]="content" id="authenticated-person-admin">
<ion-toolbar [class]="ios ? 'menu-toolbar' : ''">
<ion-title [class]="ios ? 'menu-title' : ''">
<div class="item-avatar-img" id="menu-item-avatar-img-person-admin"></div>
<div class="item-avatar-name" id="menu-item-avatar-name-person-admin"></div>
</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages_person_admin" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
Directory
You have set your templateUrl as build/app.html.
You shouldnt check it in build folder.
Try templateUrl: 'app.html' in app.component.ts
I have created an Ionic2 App using cordova FileTransferplugin, i am downloading remote server file.
Everything is working perfectly, but when I try to update template while fileTransfer.OnProgress event, the template is not updating the % downloaded.
Pleas see this video for my problem.
Ionic_youtube_link
My Code is, logic is in downloadFile function
import {Component, AfterViewInit, ViewChild} from '#angular/core';
import {NavController, NavParams, ViewController, Nav} from 'ionic-angular';
import {Page, Platform} from 'ionic-angular';
import {File, Device, Cordova, Transfer} from 'ionic-native';
import { SafeResourceUrl, DomSanitizationService } from '#angular/platform-browser';
#Component({
templateUrl: 'build/pages/video-download-modal/video-download-modal.html',
providers: [File, Transfer]
})
export class VideoDownloadModal {
selectedItem: any;
#ViewChild(Nav) nav: Nav;
videoPathUrl: string;
isPlatformReady: boolean;
platformName: string;
directoryName: string = "socialAppDir";
totalVideoSize:number;
totalDownloaded:number;
totalPercent:string = "0%";
constructor(public navCtrl: NavController, navParams: NavParams, private _viewController: ViewController, platform: Platform, private transfer:Transfer) {
// If we navigated to this page, we will have an item available as a nav param
if (platform.is('core')) {//if on dekstop
console.log('dektop');
} else {
this.videoPathUrl = navParams.get('videoPath');
console.log(this.videoPathUrl);
platform.ready().then((readySource) => {
this.isPlatformReady = true;
console.log('ready 1234');
const fs: string = cordova.file.externalRootDirectory;
console.log(cordova.file.dataDirectory);
this.platformName = Device.device.platform;
File.checkDir(cordova.file.externalDataDirectory, this.directoryName).then(() => {
console.log('directory exists');
this.downloadFile();
}, (error) => {
console.log('directory not exists');
this.createDirectory();
})
})
}
}
dismiss() {
let data = { 'foo': 'bar' };
this._viewController.dismiss(data);
}
createDirectory():void{
File.createDir(cordova.file.externalDataDirectory, this.directoryName, true).then(() => {
console.log("created externalDataDirectory");
this.downloadFile();
},(error) => {
console.log('some error happen')
})
}
downloadFile = () => {
console.log(this);
let fileName: string = this.videoPathUrl.split("/").pop();
let targetPath = cordova.file.externalDataDirectory + this.directoryName + "/" + fileName;
console.log(targetPath);
this.transfer.download(this.videoPathUrl, targetPath, true, {}).then(() => {
console.log('video downloaded')
}, (error) => {
console.log(error)
})
this.transfer.onProgress((progress) => {
console.log(this);
this.totalVideoSize = progress.total;
this.totalDownloaded = progress.loaded;
this.totalPercent = ((progress.loaded / progress.total) * 100).toString();
console.log(this.totalPercent);
})
}
ionViewDidEnter() {
console.log("enter login1");
}
}
And HTML is
<ion-content>
<div id="modalContainer" class="abd">
<ion-spinner></ion-spinner>
<br />
{{**totalPercent**}}
<br />
<button dnager block (click)="dismiss()">Exit</button>
</div>
</ion-content>
The totalPercent value either has 0 or 100.But not updating.
Please help.
This is because the totalPercent of this inside the handler was set to the global Window object instead of the object itself.
I have finally got it to work
import { NgZone } from '#angular/core';
fileTransfer.onProgress((progressEvent: ProgressEvent) => {
this.ngZone.run(() => {
if (progressEvent.lengthComputable) {
let lp = progressEvent.loaded / progressEvent.total * 100;
this.loadingPercent = Math.round(lp * 100) / 100;
}
});
})