What is the correct way to get data async before a Page
gets rendered?
Angular2
suggests the @CanActivate
decorator as far as I understand it. Sadly this is not working with Ionic2, at least not for me and for others
Apparently Ionic2
does something with the @CanActivate
decorator, see
But its not documented and i can't figure out what it does exactly.
Nevertheless this guy points out one should use Ionics View States
instead anyways, due to ionics caching. His example looks like this:
onPageWillEnter() {
return this._service.getComments().then(data => this.comments = data);
}
Which looks like he is expecting Ionic to consider the returned promise, but a quick glance a Ionics sources reveals (at least I think so) that the returned value is ignored. Hence there is no guarantee that the promise gets resolved before the page gets rendered. Here is an example with onPage* and how it does not perform as needed/expected.
So I'm lost, how does one achieve this simple task?
In the first link, it was suggested to resolve the data before navigating to the page, which burdens the knowledge which data is needed for the page on the callee. This is not an option in my opinion.
*edit: added negative example
For anyone crawling Stackoverflow about restricting page access when using Ionic 2, it looks like Ionic's recommended lifecycle event to tap into is ionViewCanEnter
.
From the docs:
ionViewCanEnter Runs before the view can enter. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can enter.
http://ionicframework.com/docs/v2/api/navigation/NavController/
I'm not sure if this is the official way to do it, but I use the Loading
component for situations like this one. You can find more information in Ionic API Docs.
The page .ts
file would look like this:
import {Component} from '@angular/core';
import {Loading, NavController} from 'ionic-angular';
@Component({
templateUrl:"page1.html"
})
export class Page1 {
// Loading component
loading : any;
// Information to obtain from server
comments: string = '';
constructor(nav: NavController) {
this.nav = nav;
}
onPageWillEnter() {
// Starts the process
this.showLoading();
}
private showLoading() {
this.loading = Loading.create({
content: "Please wait..."
});
// Show the loading page
this.nav.present(this.loading);
// Get the Async information
this.getAsyncData();
}
private getAsyncData() {
// this simulates an async method like
// this._service.getComments().then((data) => {
// this.comments = data);
// this.hideLoading();
// });
setTimeout(() => {
// This would be the part of the code inside the => {...}
this.comments = "Data retrieved from server";
// Hide the loading page
this.hideLoading();
}, 5000);
}
private hideLoading(){
// Hide the loading component
this.loading.dismiss();
}
}
The code is very simple so it doesn't need further details, the idea is to define a loading
so we can show it, then try to obtain the information, and as soon as we get that data, we can hide it calling the this.loading.dismiss()
method.
You can find a working plunker here (using beta.9)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With