Open traziusbiztest opened 5 years ago
I tried to delete
{
provide: RouteReuseStrategy,
useClass: IonicRouteStrategy
}
from app.module
But OnInit still not working
https://gyazo.com/6afec1e7936e1254b41009ab942a2d3f
How I can disable this? I need only one component, not stack
If I use custom RouteReuseStrategy I can't use route animations
Just subscribe to the params...
this.route.params
.subscribe((params: Params) => {
console.log(params['id']);
});
@digaus, This is not working, because of an old component in stack,
Hi @traziusbiztest,
Thanks for the issue! I can confirm this is a bug. By default, we cache the component when navigating (whereas a regular Angular component destroys it and re-creates it when going back). We have a fix in the works that should resolve issues where routing isn't working after the first time, params aren't being updated, etc.
Work on the fix is well underway, and I hope to have more info to share soon!
Thanks for using Ionic!
Temporary solution? How to destroy an old component in stack?
Hi there,
If you are trying to run code every time a particular page enters (or re-enters the view), you can use the ionViewDidEnter
lifecycle hook. This hook is "fired when the component being routed to has animated in": https://ionicframework.com/docs/api/router-outlet
If you are trying to respond to changes in data, you could subscribe to the data via an Observable as @digaus suggested, or you can create an injectable that holds the data. With the injectable, you can write a method that serves up the data you need.
For help on implementing either of these ideas, feel free to post on our forums or our slack.
Thanks!
i totally agree with @liamdebeasi
ngOnInit is only called, when the angular component gets initialised, which is not the case for ionic routing. the previous pages are cached and only disconnected from the change detection. The ionic component lifecycle hooks and the angular router events/observables should fulfill your needs.
It is like ionic navigation is working. Maybe it should be better documentated or clearified in the docs.
I also stumbled over this bug. I changed the lifecycle events to the ionic ones which works well on components that are accessed via the router (let's call them pages). But on components that are on this page the ionViewWillLeave
doesn't seem to be called. So the component that is on a page is not notified if the parent component is going into the cache.
Because of this I cannot unsubscribe an observable that I passed to the sub-component.
Hope this makes sense, I'll try to notify the component via an input that is called on ionViewWillLeave
of the parent component.
I also detected the same behavior when I tried to follow the tutorial of Maximilian Schwarzmüller @ https://www.youtube.com/watch?v=r2ga-iXS5i4&t=2h57m53s For me, the tutorial doesn't work anymore when it's about trying to delete positions of the list like in https://www.youtube.com/watch?v=r2ga-iXS5i4&t=3h17m0s and change back to the view which lists all positions.
I tried ionViewDidEnter
and it worked well for me. Is there any better idea?
Same bug here.
Hi, I tried to work around with this by using ionic events. I had the same problem when a route is initialized but requires re-authentication(when it tries to retrieve data(by ngOnInit) but instead get a 401 error in return because of expired token(verification happens on my backend)) so navigating to login route. After a successful login, navigate back to the previous URL to retrieve the data again. which result to the OnInit never gets called again after initialization.
I tried to use router NavigationEnd but I encountered problems, like it is firing multiple times. so i decided to use the ionic events.
I just specify the topic on publish(I used the router url as topics) and for every route subscription. so if an event.subscribe hits the right topic. It can execute a certain function(call ngOnInit again).
https://ionicframework.com/docs/v3/api/util/Events/
hope someone might find this helpful. sorry its my first time to post comment.
Please work on this issue on priority. Many are facing this issue and will start creating workarounds and/or assume ngOnInit will be loaded once and write some logic. When this behavior changes, it will cause issues in the future.
There should be a way to not cache views at all!
It seems that ngOnInit()
will fire so long as some parameters change. Using ionDidViewEnter(),
doesn't work very well because it fires after the components have been generated, causing errors.
So what I have used, is ugly, but it works. Every time I navigate to a page that I have previously visited, I append a random number (uuid to insure uniqueness) to the parameters. This causes ngOnInit()
to fire every time a page is visited.
No perfect, not pretty, but practical.
5 months still open?
Is this bug has fixed ?
@Tauqeer1 This has been fixed in the newer versions of Ionic.
It's not fixed, still facing this issue
It's not fixed, still facing this issue
@Papabeer04 Which version ? Fresh install or an upgrade using package.json ?
It seems that
ngOnInit()
will fire so long as some parameters change. UsingionDidViewEnter(),
doesn't work very well because it fires after the components have been generated, causing errors.So what I have used, is ugly, but it works. Every time I navigate to a page that I have previously visited, I append a random number (uuid to insure uniqueness) to the parameters. This causes
ngOnInit()
to fire every time a page is visited.No perfect, not pretty, but practical.
I'm getting: ExpressionChangedAfterItHasBeenCheckedError
Can you show an example of how you did it?
It's not fixed, still facing this issue
@Papabeer04 Which version ? Fresh install or an upgrade using package.json ?
5.2.4
My problem remains with a modal, when I open the modal and close it and go to another page. Then go back to the page and open the modal again ionViewWillEneter and ionViewDidEnter don't work.
ionViewWillEnter fixed my normal pages at the moment.
I used ionViewWillEnter() instead of ngOnInit(). It works,
I did some investigations. Hope it helps Ionic version @ionic/angular 4.11.1
Actual result I have 2 pages: Welcome, Login and I just navigate forward, don't have any back navigation. Scenario 1
Scenario 2
Expected Result From log I should see 2 lines of log for Login page OnInit event.
Thanks for improving this framework!
Guys. Please don't say I use ionViewWillEnter and it works. What does temporary solution mean for you? What @liamdebeasi suggest is using ionViewWillEnter when "run code every time a particular page enters" and it is acceptable solution for this case only. How about the other cases? You will get temporary solution and use another temporary solution because this temporary solution make. You might ask why. I will show you how Ionic ionViewWillEnter and Angular ngOnInit different in log. Ionic-Angular already different when it fires component events.
Angular LoginPageComponent constructor ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit ngAfterViewChecked
Ionic-Angular LoginPageComponent constructor ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked ngAfterViewInit ngAfterViewChecked ngDoCheck ngAfterContentChecked ngAfterViewChecked ngDoCheck ngAfterContentChecked ngAfterViewChecked ionViewWillEnter ngDoCheck ngAfterContentChecked ngAfterViewChecked ionViewDidEnter ngDoCheck ngAfterContentChecked ngAfterViewChecked ngDoCheck ngAfterContentChecked ngAfterViewChecked
My problem remains with a modal, when I open the modal and close it and go to another page. Then go back to the page and open the modal again ionViewWillEneter and ionViewDidEnter don't work.
ionViewWillEnter fixed my normal pages at the moment.
@Papabeer04 , I'm facing with the same issue just as you wrote. Did you able to fix the issue?
When will ionic team fix this issue? As far as I see it's not a new one...
Dear All, @traziusbiztest @liamdebeasi @Papabeer04 @kamvir @thinkdj
I have tried all the above suggestions but no luck for me. Please let me know what I need to do as I am also facing same problem.
Why ngOnInit() works only once when I come back to home page the data not displaying. :(
Please help me. Thanks in advance.
Mozib Khan
For me the problem was actually in my service. I followed the course of Simon Grimm but he makes a mistake.
(Using firebase)
service.ts :
constructor(private afs: AngularFirestore) {
this.ideaCollection = this.afs.collection<Idea>(ideas);
this.ideas = this.ideaCollection.snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return { id, ...data };
});
})
);
}
getIdeas(): Observable<Idea[]> {
return this.ideas;
}
Should be:
constructor(private afs: AngularFirestore) {
this.ideaCollection = this.afs.collection<Idea>('ideas');
}
getIdeas(): Observable<Idea[]> {
return this.ideas = this.ideaCollection.snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return { id, ...data };
});
})
);
}
For me the problem was actually in my service. I followed the course of Simon Grimm but he makes a mistake.
(Using firebase)
service.ts :
constructor(private afs: AngularFirestore) { this.ideaCollection = this.afs.collection<Idea>(ideas); this.ideas = this.ideaCollection.snapshotChanges().pipe( map(actions => { return actions.map(a => { const data = a.payload.doc.data(); const id = a.payload.doc.id; return { id, ...data }; }); }) ); } getIdeas(): Observable<Idea[]> { return this.ideas; }
Should be:
constructor(private afs: AngularFirestore) { this.ideaCollection = this.afs.collection<Idea>('ideas'); } getIdeas(): Observable<Idea[]> { return this.ideas = this.ideaCollection.snapshotChanges().pipe( map(actions => { return actions.map(a => { const data = a.payload.doc.data(); const id = a.payload.doc.id; return { id, ...data }; }); }) ); }
Wow! you are great it works for me.
Thank you so much @Papabeer04
Please get in touch via my skype (chaton_skype)
Thanks,
Mozib
Try this:
constructor(
private zone: NgZone
) {}
this.zone.run(() => {
this.router.navigateByUrl('/login', { skipLocationChange: true });
});
This is happening because ionic router caches pages. If the page is cached only ionViewWillEnter
will be called.
But if a page wasn't cached then ngOnInit
will be called every time
Still facing issue with @ionic/cli version v6.4.1
(_) (_) | |/ | '_ | |/ _| | | () | | | | | ( |_|_/|| |||\| CLI 6.4.1
Any updates ? Ionic 5 still having this issue.
Hi, I tried to work around with this by using ionic events. I had the same problem when a route is initialized but requires re-authentication(when it tries to retrieve data(by ngOnInit) but instead get a 401 error in return because of expired token(verification happens on my backend)) so navigating to login route. After a successful login, navigate back to the previous URL to retrieve the data again. which result to the OnInit never gets called again after initialization.
I tried to use router NavigationEnd but I encountered problems, like it is firing multiple times. so i decided to use the ionic events.
I just specify the topic on publish(I used the router url as topics) and for every route subscription. so if an event.subscribe hits the right topic. It can execute a certain function(call ngOnInit again).
https://ionicframework.com/docs/v3/api/util/Events/
hope someone might find this helpful. sorry its my first time to post comment.
I had the same problem as @irealyze on Ionic 5
ionic 5 still the problem persist
i also had trouble with this issue (refactored my navigation from tabs to pages thinking these would solve the on init issue), but it seems to be a general issue where a clear workaround/guidance for exists
the current docs of ionic tell how to deal with it:
https://ionicframework.com/docs/angular/lifecycle#how-ionic-handles-the-life-of-a-page https://ionicframework.com/docs/angular/lifecycle#guidance-for-each-life-cycle-method
guidance says:
Hi @traziusbiztest,
Thanks for the issue! I can confirm this is a bug. By default, we cache the component when navigating (whereas a regular Angular component destroys it and re-creates it when going back). We have a fix in the works that should resolve issues where routing isn't working after the first time, params aren't being updated, etc.
Work on the fix is well underway, and I hope to have more info to share soon!
Thanks for using Ionic!
What's the progress of this issue? Do we have plan to fix it? Or is there an official suggestion how we should handle with it.
Like @kamvir said I used ionViewWillEnter() instead of ngOnInit() and it works.
Note that this is not a pages only problem. The Ionic Life Cylce events like ionViewDidEnter
etc are great and should be used in pages. But it does not work with other components. So if you have a standalone component that expects ngOnInit
to be called every time you view a page, it won't work. Is there no workaround? Different routing strategy etc.
In best case we need an event which is called only once on page enter (but not on nav back), like the current behavior. And an event called every time the page gets in view. An event for all components. Not only pages. Or a mode which destroys the page on forward navigation. Maybe just a config question. Root navigation may also help. But will not work with back navigation I guess. Or listen to router.events
. Or you can set the attr. replaceUrl="true"
on the element with routerLink
.
I've managed to fix the issue this way:
On page components, I can use ionViewDidEnter
, ionViewWillEnter
, etc.
I discovered that components don't call those events, but they are always recreated everytime Ionic enters the view, therefore, for components, OnInit()
will be called everytime, and for pages, it's being called just once (because the page component is created only once, duh).
If you use it like this, you won't have issues.
ionViewWillEnter
etc does not work on components. Only for pages. Is there no solution to fully load the page again on back navigation? Or another solution to have the same behavior like in Ionic 3.
This problem took me by surprise but tbh jokes on me for not reading the documentation which clearly states how it works https://ionicframework.com/docs/angular/lifecycle#how-ionic-handles-the-life-of-a-page Coming from angular it was a bit of a shock that ngOnInit wasn't called all the time though but fair enough, given all that's said in the docs I don't see that as an issue anymore.
Hi all,
we (Myself and @veeravetrivel) have tried with the following workaround and its working fine for us.
He already raised a new ticket for this. But unfortunately, they closed it without any strong solution for that and just asked us to follow ionic life cycle hooks
https://github.com/ionic-team/ionic-framework/issues/23765
So, we tried to find a workaround and its working fine for us. Hopefully it will also work for others who are stucked up to reinstantiate the already routed angular component.
The following workaround will remove the previous route component from the pages stack and place only the routed current component in the stack.
And called the previous route component's ngOnDestroy. And called the current route component's constructor and ngOnInit.
import { NavController } from '@ionic/angular';
constructor(
public navController: NavController
) {
}
navigatePage1() {
this.navController.pop();
this.navController.navigateBack('/page1');
}
navigatePage2() {
this.navController.pop();
this.navController.navigateBack('/page2');
}
Note: We don't face any side effects using this implementation and its working fine with respect to angular life cycle hooks. If someone facing any issue then, only admin can help us exactly the internal behavior or side effects with respect to ionic life cycle hooks to use this APIs
I've ended up with custom RouteStrategy
where shouldReuseRoute
is either configured via data
in routing to return false or not. Or if you need always have all life cycles on all pages than shouldReuseRoute
need to return false. Looks like this worked for us after juggling with Pages with Tabs and Components in them that need to be reinited.
what about in the new version please???
I faced the bug today, 2019 - 2023, and the bug still here, any solution for this?
I have to vent a bit first: some of the decisions by Ionic team has killed the soul of Angular IMO. Those beautiful self contained components are no more.
My current two workarounds to access router snapshot is either through a resolver, or to always navigateRoot to a component (forcing Ionic to create the component again and not use a cached version).
One of the interesting things you will face with Ionic if you are new to it (not exactly related to your issue here), is that sometimes it decides to call the Ionic life cycle hooks and sometimes it doesn't; so don't trust them all the time either (from what I remember if it's a Page or Component that is called by router then Ionic lifecycle hooks are called on it, if it is a component embedded in a top component then they are not)
I faced the same issue when the authentication router guard navigated to the login page and then back to the home page, resulting in neither the ngOnInit() nor ionViewWillEnter() methods being executed. Here is my solution: On the page where you want to call ngOnInit() or ionViewWillEnter() more times:
import { ActivatedRoute, Router, Event, RouterModule, RouterEvent, NavigationEnd } from '@angular/router';
// In constructor
const currentUrl = this.router.url;
this.router.events
.pipe(
filter((e: Event | RouterEvent): e is RouterEvent => e instanceof RouterEvent),
filter(e => e.url === currentUrl)
)
.subscribe(
(event: RouterEvent) => {
if (event instanceof NavigationEnd) {
console.log(event);
// Do something
}
});
This code listens for router event changes and refreshes the current component if the navigation URL matches the current component route URL
Update: Using this.navController.navigateRoot() instead of this.navController.navigateForward() or this.router.navigate resolved my issue. Additionally, note that the ionViewWillEnter lifecycle will run multiple times if the previous page was navigated using this.navController.navigateRoot().
Still facing this issue intermittently in Ionic 7, five years after this issue was originally filed!
Observables are being refreshed for pages that I didn't initially load in on and first accessed via the router, but whatever page I started on will never refresh!
Bug Report
Ionic version: [x] 4.1.0
Current behavior: Ionic router run OnInit only first time
Expected behavior: Run OnInit each time
I have an app with Angular. It is a simple list of items, after clicking on an item opened item details page. Two routes:
I use ItemsService -> get/save items.
In Angular application, OnInit lifecycle event working each time when I open these pages. And it is fine. I should edit an item on ItemDetailsComponent, and after clicking back to IndexComponent I see new information.
I start an Ionic project. Changed
router-outlet
toion-router-outlet
Same structure, same routing. And now:IndexComponent OnInit working the only first time. When I back to this page from ItemDetailsComponent - OnInit not rerun. Ionic reuse IndexComponent, But I need a new instance.
ItemDetailsComponent OnInit working the only first time for each item in the items list. But if I edit an item, return back to IndexComponent, update items handly(click a button, because OnInit not work). And open ItemDetailsComponent again - I see old information because OnInit not firing - this is an old instance.