When we would not want to reinitiate a task that is already cache, there is no doubt that we will be using ionDidLoad
.
Now, let's make assumption that we need to do a task each and every time when we are entering a view, how do we choose between using ionViewWillEnter
vs ionViewDidEnter
.
I did not find any clear guideline on this.
For example:
1) Getting navParams
2) Calling REST api
3) Declaring variable
4) Initiate something after DOM element loaded completely (eg: google map init)
Additional note:
I am note looking for an answer that is clearly written in the ionic documentation. What am I intend to know is what is the pros and cons if put in ionViewWillEnter
vs ionViewDidEnter
eg: Initiating in ionViewDidEnter
will cause some delay (for example, i am not sure about this) - even the insignificant one
ionViewWillEnter : It's fired when entering a page, before it becomes the active one. Use it for tasks you want to do every time you enter in the view (setting event listeners, updating a table, etc.).
First, about ionic life cycle. If you write down all ionic events and put a console. log in each, you will see the scenario: constructor --> ionViewDidLoad --> ionViewWillEnter --> ionViewDidEnter --> ionViewWillLeave --> ionViewDidLeave --> ionViewWillUnload.
Ionic Lifecycle MethodsFired when the component routing to has finished animating. ionViewWillLeave. Fired when the component routing from is about to animate. ionViewDidLeave. Fired when the component routing to has finished animating.
sebaferreras answer is great but it is missing some points.
First, about ionic life cycle. If you write down all ionic events and put a console.log
in each, you will see the scenario:
constructor --> ionViewDidLoad --> ionViewWillEnter --> ionViewDidEnter --> ionViewWillLeave --> ionViewDidLeave --> ionViewWillUnload.
constructor
run first when the page is initiated. This is the best place for you to declare default values for your variables.ionViewDidLoad
is fired when the view is completely loaded. It means you can attach DOM element here. ionViewWillEnter
runs when the page is about to enter and become the active page. ionViewDidEnter
runs when the page has fully entered and is now the active page. ionViewDidEnter
will fire after all synchronous in ionViewWillEnter
completed. To prove it, just put heavy code into ionViewWillEnter
:
ionViewWillEnter(){ console.log("ionViewWillEnter") for(let i = 0; i < 100000; i++){ console.log(i); } } ionViewDidEnter(){ console.log("ionViewDidEnter") }
Run your code and you will see it take so long time to launch your page. So never put heavy synchronous code into ionViewWillEnter
. Just use asynchronous in ionViewWillEnter
and move all synchronous code to ionViewDidEnter
. Because in there, your page is entered and it will make a better UX.
The answer is quite simple and, as always, the best way to see what's going on behind the scenes is to inspect the source code of Ionic.
Long story short: the ionViewWillEnter
lifecycle hook is triggered before the page transition begins, and the ionViewDidEnter
is triggered after the transition finishes. Please take a look at the end of this answer to see the reference to the source code.
So, when you should use each of these hooks? There must be several possible scenarios, so these are only a few ideas based on some applications I've worked on.
Sometimes you want to update some information on the page every time the user opens that page; that may require making an HTTP request to a remote API to fetch some data. In that case, we could say that using the IonViewWillEnter
seems like the right option, so you can make the request as soon as possible, obtaining the response sooner as well.
The same applies when you need to interact with the DOM for some reason because the DOM has been already loaded when the IonViewWillEnter
is executed, so this could help you to initialize the page as soon as possible, and with a little bit of luck the page could be shown to the user ready to be used.
The same is valid when you need to initialize the view with some parameters that you get from the previous view. In this case, since it's a very simple operation, you can use the ionViewWillEnter
lifecycle hook and the view will be shown already initialized to the user.
So when should you use the ionViewDidEnter
then?
I've noticed that sometimes when executing the app on very old android devices (with less than 512mb - 1gb RAM), the animation can be a little bit lagged when making a request to the API in the ionViewWillEnter
, so it'd be a good idea to make these requests to the API in the ionViewDidEnter
to make sure that the animation is finished
In some apps I've been asked to include some fancy animations to the elements of the pushed page, like bringing part of the content from the bottom, fading some other elements after a delay, and so on. You could use angular animations for that (in order to be able to have control over the timing), and the best way to avoid some lag on these animations would be to use the ionViewDidEnter
hook. This also will allow you to make the user feel like the animations of the elements within that page are a continuation of the transition of the page itself.
You can take a look at the NavControllerBase code:
IonViewWillEnter
// around line 666... _transitionStart(...): Promise<NavResult> { // ... // around line 700... // create a callback that needs to run within zone // that will fire off the willEnter/Leave lifecycle events at the right time transition.beforeAddRead(this._viewsWillLifecycles.bind(this, enteringView, leavingView)); // ... }
And...
// around line 805... _viewsWillLifecycles(enteringView: ViewController, leavingView: ViewController) { if (enteringView || leavingView) { this._zone.run(() => { // Here, the order is important. WillLeave must be called before WillEnter. leavingView && this._willLeave(leavingView, !enteringView); enteringView && this._willEnter(enteringView); }); } }
If you inspect the beforeAddRead
method from the animation.d.ts
definition you'll see:
/** * Add a function which contains DOM reads, which will run * before the animation begins. */ beforeAddRead(domReadFn: Function): Animation;
So now we can be sure that the ionViewWillEnter
lifecycle hook is executed before the page transition begins
IonViewDidEnter
This one is a little bit simpler. Again in the same NavControllerBase
:
// around line 743... _transitionFinish(...): NavResult { // ... // around line 753... if (hasCompleted) { // transition has completed (went from 0 to 1) if (enteringView) { enteringName = enteringView.name; this._didEnter(enteringView); } // .. } // ... }
And
// around line 939... _didEnter(view: ViewController) { assert(this.isTransitioning(), 'nav controller should be transitioning'); assert(NgZone.isInAngularZone(), 'callback should be zoned'); try { view._didEnter(); this.viewDidEnter.emit(view); this._app.viewDidEnter.emit(view); } catch (e) { this._errHandler && this._errHandler.handleError(e); } }
So because of that, we can say that the ionViewDidEnter
lifecycle hook is triggered after the transition finishes.
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