How to implement HUD (spinner / activity indicator) in ionic 2? - web-services

What is equivalent code for $ionicLoading. If I have below code snippet how can I set up loading HUD for every http request in a config file. (i.e. It will automatically add HUD when application calls a web-service)
makePostRequest() {
this.http.post("https://domain/post", "ur=kkr")
.subscribe(data => {
//Done loading, stop!
}, error => {
console.log(JSON.stringify(error.json()));
});
}

Please check this
let loading = Loading.create({
content: "Please wait...",
duration: 3000
});
this.nav.present(loading);
go through loading ionic2 - documentation

Related

Ionic Deep linker view does not update on browser back button event

I have a PWA built with ionic deep linker. I have done a demo here https://stackblitz.com/edit/ionic-mee2ut?file=app%2Fcustomer%2Fcustomer.component.html where the browser back button doesn't work as expected.
Steps to reproduce
1.In Dashboard page click on edit button.It will navigate to customer
page(see URL.It is changed to /Customer/CustomerId).
2.In Customer page, you will see the customer info and other customers
list, there click edit from other customers list.This will open another
page.(see URL.It is changed to /Customer/CustomerId).
3.Click on browser back button u can see that the URL is changed but the
view is not updated.
If I repeat steps 1 & 2 then click on nav back button instead of browser button then it works correctly.Both the URL and the view gets updated.
Is there something I am doing wrong because the browser back button does not work as expected or this is issue of ionic framework.
This is how i navigate between views
EditCustomer(Customer: any) {
this.navCtrl.push('Customer', { Id: Customer.Id, Name: Customer.Name });
}
Can somebody please tell me a way how to resolve this issue?
I saw your code in the above url, you are passing id as param but not the name so, that is the reason url is changing but data is not reflected i modified your code in app.module.ts file please replace this code in your app.module.ts file
IonicModule.forRoot(MyApp, {}, {
links: [
{ component: DashboardComponent, name: 'Dashboard', segment: 'Dashboard' },
{ component: CustomerComponent, name: 'Customer', segment: 'Customer/:Id/:Name' }
]
})
Please replace your app.module.ts with the following code
import { Component } from '#angular/core';
import { Platform, IonicApp, App } from 'ionic-angular';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = 'Dashboard';
constructor(private _app: App, platform: Platform, private _ionicApp: IonicApp,) {
platform.ready().then(() => {
this.setupBackButtonBehavior();
});
}
private setupBackButtonBehavior () {
// If on web version (browser)
if (window.location.protocol !== "file:") {
// Register browser back button action(s)
window.onpopstate = (evt) => {
//Navigate back
if (this._app.getRootNav().canGoBack())
this._app.getRootNav().pop();
};
}
}
}
I was able to use something like this:
let randomID = this.makeId(5); // random string id
this.navCtrl.push('path', {
eventID: eventID,
instituteID: instituteID,
randomID: randomID
}, {
id: `path/${eventID}/${instituteID}/${randomID}`
});
This "id" seems to fix it, but if you can go to the same page, then it requires a "random" value to separate each visit to that page.
#IonicPage({
name: 'path',
segment: 'path/:instituteID/:eventID/:randomID'
})
It looks like, by default, it uses the name of the page as an id for that view. If multiple views have same id => issue when using browser back/forward. That's where the random comes in, to separate multiple instances of the same page.

managing browser history in iframe onclick hardware back button ionic 2

I am new to ionic framework and I am unable to manage hardware back click functionality in Iframe. I am using Iframe to load certain url. While clicking the hardware back button I should be able to navigate back to the browser history page. But whenever I click hardware back its exiting the app.
`<iframe #iframe id="iframe" style="height: 100%;width: 100%;" src="your url"></iframe>`
#ViewChild('iframe') iframe:ElementRef;
constructor(public platform:Platform,public nav:Nav){
platform.registerBackButtonAction(() => {
if(this.nav.canGoBack()){
this.iframe.nativeElement.contentWindow.history().back();
}
});
}
You can use window.history.back():
ionViewDidLoad() {
this.navBar.backButtonClick = (e: UIEvent) => {
window.history.back();
}
this.initializeBackButtonCustomHandler();
}
ionViewWillLeave() {
// Unregister the custom back button action for this page
this.unregisterBackButtonAction && this.unregisterBackButtonAction();
}
initializeBackButtonCustomHandler(): void {
this.unregisterBackButtonAction = this.platform.registerBackButtonAction(function(event){
window.history.back();
}, 101); // Priority 101 will override back button handling (we set in app.component.ts) as it is bigger then priority 100 configured in app.component.ts file */
}
More info about this method can be found here.

Ionic 2: Loading screen does not get dismissed

I have an application made with Ionic 2, The work flow is like this
Case A . When user is using app for the first time
User Logs in (loading is shown)
When successfully logged in loading window is hidden and user is forwarded to Dashboard page.
In dashboard page items are loaded via ajax request.
Case B. When user is already logged in before
The first screen is Dashboard and items are loaded via ajax request.
Problem
In case A, when user logs in and forwarded to DashboardPage, the loading screen doesn't gets dismissed. Sometimes it gets dismissed but most of the time it doesnot? Is this an ionic bug or am I doing something wrong??
Here is my DashboardPage
//imports here
export class DashboardPage {
public loadingmsg: any;
public ajaxRequest: any;
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private webservice: WebService,
private loadingCtrl: LoadingController
)
{
this.loadDashboardContents();
}
loadDashboardContents(){
//other codes
this.loadingmsg = this.loadingCtrl.create({
content:"Loading contents, please wait..."
});
this.loadingmsg.present();
this.ajaxRequest = this.webservice.getDashboardContents(params).subscribe(data => {
this.loadingmsg.dismiss().then(()=>{
//other codes to save retrieved data to localstorage.
});
});
}
}
UPDATE
The login method from login page
loginUser(){
this.loading=this.loadingctrl.create({
content:"Logging in, please wait..."
});
this.loading.present();
this.ajaxRequest = this.webservice.loginUser(params).subscribe(data => {
this.loading.dismiss();
if(data.status =="ok"){
this.navctrl.push(DashboardPage).then(()=>{
const index = this.viewCtrl.index;
this.navctrl.remove(index);
});
}else{
//show error alert
}
}, err =>{
this.loading.dismiss();
});
}
My Ionic and cordova version information
Ionic Framework: 3.5.0
Ionic App Scripts: 1.3.9
Angular Core: 4.1.3
Angular Compiler CLI: 4.1.3
Node: 6.10.3
OS Platform: Windows 10
Cordova Version: 6.5.0
I am currently using loading in my project and it works well in all case. To ensure loading will always dismiss you need to add some code:
1. duration, dismissOnPageChange
let loading = this.loadingCtrl.create({
content: "",
duration: 5000, //ms
dismissOnPageChange: true
})
2. dissmis when ajax call success or error:
.subscribe(success=>{
//some code
loading.dismiss();
},error=>{
//some code
loading.dismiss();
})
It may be due to the this reference inside your subscribe method. I would try declaring loadingmsg locally and removing this.
loadDashboardContents(){
//other codes
let loadingmsg = this.loadingCtrl.create({
content:"Loading contents, please wait..."
});
loadingmsg.present();
this.ajaxRequest = this.webservice.getDashboardContents(params).subscribe(data => {
loadingmsg.dismiss().then(()=>{
//other codes to save retrieved data to localstorage.
});
});
}

LoadingController, Ionic2, Disappear automatically when using, dismissOnPageChange: true

I am using loadingController Ionic2.
`fetchNotificationListAferUserDataget(){
this.loader = this._loadingController.create({
content: "Please wait... Fetching online notifications",
dismissOnPageChange:true
});
this.loader.present();
this._userDataService.getNotificationList()
.subscribe(
(data) => {
this.loader.dismiss();
let status = data.status;
let returnedData = data.json();
console.log(status,returnedData)
if(data.status == 200){
if(returnedData.notifications.length > 0){
this.notifications = returnedData.notifications;
console.log(this.notifications);
this.loader = this._loadingController.create({
content: "Please wait... Fetching your purchased packages"
});
this.loader.present();
this._userDataService.getAllPackageByUser(this.userData.user_id)
.subscribe(
(data) => this.populateUserPackages(data),
(err) => this.showDataFetchErrorFromServer('Unable to fetch user packages')
)
}else if(returnedData.notifications.result == 0){
console.log('no notifications found');
}
}
},
(err) => {
this.showDataFetchErrorFromServer('Unable to fetch notifications')
}
);//end .subscribe
};`
But the problem I am facing is that loader appear and disappear automatically without my calling loader.dismiss();
Does anyone else facing same issue. Any solution for this.
EDIT: Full Function code included. loader dismiss immediately after loader.present(), without any error, but when I call this.loader.dismiss();, it gives me error because loader is already dismissed.
According to this issue, it is caused by triggering the loader.present() on the wrong life-cycle hook. I also had the same problem, where I had the loader loading on the ionViewDidLoad() hook. "The dom is not guaranteed to be ready in ionViewDidLoad and events are not guaranteed to be ready."
Try presenting the loader on the ionViewDidEnter() hook instead.
You need to use setTimeout() for this. Like:
setTimeout(() => {
this.loader.dismiss();
}, 1000);
Also, please do not use the same variable this.loader for creating 2 loaders. Just use a local variable like var loading = this._loadingController.create(). This could create problems in Loading API. In ionic 2 documentation here, it is mentioned:
Note that after the component is dismissed, it will not be usable anymore and another one must be created. This can be avoided by wrapping the creation and presentation of the component in a reusable function as shown in the usage section below.

How to close popup on ionic2 app

I have an ionic2 application with angular2, at one page I inject LoadingController and make use of it, at different location on my app.ts I catch all global http errors and want to display alert so I inject AlertController there .
So having 2 location which can at some point call a modal dialog creation and present it causing a problem that freezes the screen , I believe it is because there are 2 modals being open one on the other.
Is there any chance I can grab the current dialog and close it, or add param to create which closes any background modal ?
This is my code:
export class SandboxPage implements OnInit {
private _loadingModel;
constructor(private _navCtrl:NavController, private _alertCtrl:AlertController , private _loadingCtrl: LoadingController ) {
}
ngOnInit() {
this._loadingModel = this._loadingCtrl.create();
this._loadingModel.present();
let alert = this._alertCtrl.create({
title: 'Error',
message:"error message",
buttons: [{
text: 'Ok',
handler: () => {
// user has clicked the alert button
// begin the alert's dismiss transition
let navTransition = alert.dismiss();
}
}]
});
//timeout the error to let other modals finish dismissing.
setTimeout(()=>{
alert.present();
},500);
}
}
The ok click want close the alert model, Here in this example it's on the same page so I can dismiss the loading but when on different components it's not possible to do.