It would be useful to be able to pass parameters back in the navigation.
Currently, we can use this.nav.push(NextPage,NavParams) to send information to the NextPage, but no way to receive information back when NextPage is closed.
Would be nice to have something like this.pop(NavParams) where the NavParams could be delivered to onPageWillEnter(NavParams) method in the parent Page.
Ionic Version: 2.x
Browser & Operating System: iOS / Android / Chrome
Right now I am getting around the issue by pushing the parent as a NavParam to the child, so
nav.push(ChildPage, {delegate: this});
Then when it is time to pop the child page off, I have pass the data to the delegate before hand. This method works okay but it couples your views together.
I think this is a good idea, just not sure on the best API for this yet. There's a few ways we can pull this off, but I want to make sure it's easy enough to understand and use without causing more issues. When going forward, push(Page, data)
is pretty easy because that page knows exactly what should happen, and was passed the exact data to load. However, when it is the entering page from a pop()
, the entering page isn't sure how it came about being the active page again, and the constructor wouldn't fire again since it's still instantiated.
I like the idea of passing data to onPageWillEnter(leavingPageData)
and onPageDidEnter(leavingPageData)
. It's pretty generic and similar to how the constructor NavParams work. All pages themselves should have no clue where they live in the nav stack, and what pages come before and after them.
So the question is, what's the easiest way to wire up data getting passed from the leaving page, to the entering page? Because both the leaving page and entering page require some sort of API, and preferably something familiar to how data is passed around in Ionic2 and ng2.
One idea is to have the leaving page's onPageWillLeave()
return some data, which then gets passed as the argument in the entering page's onPageWillEnter(leavingPageData)
, but I'm just not sure about that API yet.
Any other thoughts?
For keeping it clean, maybe use the same system has modal with a "dismiss" like function with you can put data in there and subscribe to a callback :
MyFirstPage :
goToMyPage() {
nav.push(MyPage);
MyPage.onPop(data => {
console.log(data);
});
}
MyPage :
dismiss() {
this.viewController.dismiss(data);
}
The modal Page is wrapped in a Modal instance, the way we open a new Page today is by passing the class to nav.push(), so we would need to create an wrapper to push pages too.
I am not an IOS developer, but the way Android framework works is by setting an REQUEST_ID when opening the child Page and returning it to the callback method in parent Page when the child pops out. So the parent page can validate from where come pop call. It helps when the parent has more than one possible child.
Something to keep in mind too is that, onPageWillEnter
is triggered when swapping from a tab to another.
@adamdbradley, is there any chance of this to be included in the betas for v2? This is something I really need.
Any solution to this (pop and pass nav params) yet?
Also looking for an easy solution for this. Have a settings page and want to refresh the original view when navigating back after settings have been changed. Some sort of hook that I can put in onPageWillLeave
to pass data back to the previous view. I guess potentially:
onPageWillLeave(nextViewParams) {
// modify the next/back view params here
nextViewParams.settingsChanged = this.dirty;
}
Also looking into the same functionallity, as it could mimic the look, behaviour and feel of the native iOs select boxes.
@adamdbradley Passing the data in the pop is easy and familiar because you're using it for .push() just the same. Retrieving the data in the parent inside onPageWillEnter() is a good option.
I guess a developer knows what he's doing when he'll pop some data to another page. In the rare occasion this data is uncaught, I guess it's not going to hurt?
I have this need as well. I've been digging into NavController and ViewController, but so many methods are private that any use of their internals would be a tenuous hack.
You can get data back by keeping a reference to an object provided to NavParams:
Parent:
this.nav.push(Child, {container: this.myDataContainer});
Child:
this.navParams.get('container').foo = 42;
Idea: this.push could return a Promise.
This indicates a clear connection with the specific ChildPage and its arguments and the resolution code in the Parent.
this.push(ChildPage).then(dataFromChild => {
// do stuff with data resolved from Child
});
Then either put the Promise as a parameter of the Child's enter methods onPageDidEnter(promise)
Or maybe inject it?
constructor(parentPromise: ParentPromise)
However, for this to work, the Parent instance cannot be unloaded. Does Ionic2 promise to not unload Pages in the Nav stack?
The second issue is that developers may assume that the Parent Page's resolution code (function in .then) is executed when the Page is active. The documentation could highlight this issue and Developers could code around this by saving the data and then retrieving it in onPageDidEnter() or just saving the Promise and calling .then in on enter methods.
this._childPromise = this.nav.push(ChildPage);
onPageDidEnter() {
if (popFromChildPage) {
this._childPromise.then(data => {
// do stuff
}
}
}
But at the moment, the code to determine if nav popped from a particular ChildPage is a bit awkward. And now there's this disconnection between the push and the resolution code.
So maybe ParentPromise could be a special Promise that does not call .then immediately when resolved. Instead, it waits for the Parent Page to be active again, and then if resolved/rejected, invokes then/error.
Also, one might argue that you want an Observable instead, or to control whether to use the active view Promise behavior. So maybe something like this:
this.nav.push(ChildPage).observe().subscribe(data => {
});
this.nav.push(ChildPage).observe({whenPageActive: true}).subscribe();
this.nav.push(ChildPage).promise().then(data => {
});
this.nav.push(ChildPage).promise({whenPageActive:true}).then();
What do people think?
Now that I think about it more, I don't think the whenPageActive concept is a good idea. What if there's a navigation from the ChildPage to a completely different part of the app? Do whenPageActive Promises only fire when the nav stack is preserved? i.e. A pop() from Child. It just raises more confusion and makes this feature more complicated than needed.
Better to just remind developers that the Promise/Observable will be getting data while the Page is not active and to design their code appropriately.
At the moment, you can pass a Promise through NavParams with code like this:
Parent
new Promise((resolve, reject) => {
this.nav.push(ChildPage, {resolve: resolve});
}).then(data => {
// process data
});
Child
this.navParams.get('resolve')('some data');
The Promise creation code is just a bit awkward.
+1 on this? Should we expect this feature in the near future or go for the hack approach? Please advise. Thanks!
Just spent a few hours failing with this before finding out I was attempting the impossible (with current API). +1 from me please.
Please, add this feature.
On Thu, Jun 9, 2016 at 6:41 AM, Matt Beckett [email protected]
wrote:
Just spent a few hours failing with this before finding out I was
attempting the impossible (with current API). +1 from me please.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/driftyco/ionic/issues/5724#issuecomment-224847336,
or mute the thread
https://github.com/notifications/unsubscribe/AFrI2as2QYcLNfcuJ2GxtWruestEA19lks5qJ9_agaJpZM4HpsWx
.
One thing to consider is how the Nav Stack will be re-created in different situations (these features may not exist now, but I'm guessing this is something Ionic may do in the future):
In these situations, Ionic would need to recreate the Nav Stack based on Pages and NavParams. So if developers want this functionality in the future, all Page state should be derived from NavParams. And the values need to be serializable, probably just strings if you want deep-linking via a URL.
So based on this, I'm no longer in favor of my Promise idea or giving child pages a reference to the parent Page or a data container object.
I think @BugsBunnyBR original idea of being able to modify or add NavParams to the parent as you pop may be the way to go.
One could argue that you just shouldn't do this because it over-complicates Page state and navigation; instead developers should just handle such cases with Services that marshal data between Pages.
@jgw96, @adamdbradley and all ionic team, what the hell? This is a basic need for Ionic2, we are already in the beta9 and this is not even in the milestones. It`s nice to have buttons and menus that look like the native ones, but this issue is far more important! This is related to the basic architecture of a mobile application! I could wait for that bunch of nice things you all developed since this issue was raised, but missing this feature makes a app development far more complicated than it should.
@BugsBunnyBR Hey there! We understand your frustration.
At the moment, while we want to do this, it would require heavy changes to the current navController API that could break many apps out there.
There are some alternative ways though that can help you.
1) Pass data to a DataService and having it be in charge of maintaining state.
2) Pass the original component along during the first navigation and modify the data needed then.
This is something we know we need to have, but we want to make sure we have a solid base first
Sorry for being so quiet on this one!
@mhartington Don't worry about it :-)
I'm also in the camp that considers this feature a necessity, but I'd vastly prefer to wait and have it well made than to have it breaking things right now :-)
Thanks for all of your hard work Ionic Team :-)
And thanks for adding it to the milestones #^-^#
Also, you can pass an instance of you component to the next page when you push.
this.nav.push({parent: this});
Definitely I don't like the idea of passing data through pop, unless someone can demonstrate an use case that can not be implemented with:
Thanks @mhartington for the reply, I also understand that this might be big change and there may have issues related to it, but the later it is defined/implemented, more apps will break, lots of people already have ionic2 in production (without getting in the merit of they should or not) or are, at least, already developing using it.
I am using a static data service at the moment, but the need to clear the data once it is used in the parent page and not having a especifique trigger saying "Hey, I am back from that page that should return some data" makes me need to evaluate at each ionViewDidEnter
, it triggers web services and redraws in the screen.
I don't like the idea of passing the component because it would bind my pages to the calling one...maybe if I make it implement an interface it would solve the problem..
A modal is not 100% the same as a page, so it does not solve the issue here, to navigate from modal to modal and back just seems wrong.
Thanks for adding this in the roadmap.
+1
For what it's worth, I did what @manucorporat suggested by passing this
as a parent
property on the NavParams
and added an onWhatever(someData)
method to my parent Component... then, from the child Component, I called parent.onWhatever(...)
right before popping back to the parent and it worked like a charm. I'm pretty happy with that interaction. Perhaps this pattern should be added to the NavController documentation so we get a quick idea as to how this might be accomplished without having to google around?
Will use one of the suggestions above to handle my situation but I'd love this feature too :)
+1
Which workaround is best for this?
Have sticked around to passing the parent to child for now
is this available on rc0?
Could this be done by raising an event with some data and then the parent page could subscribe to that change. After all the push/pop navigation isn't structured, anything could push a page and where you pop back to isn't always the same type of parent page, i.e. the home page or some other completely different page.
So if you had a 'settings' page that could be pushed from anywhere, when closing that or 'saving', just raise an event first with the data that might be of interest before poping. Even just a 'settings have been updated, go reload them' event. Then anything subscribing to that event can respond and process accordingly.
@kabus202 I'm on RC0, it's not available yet (or at least, I don't see it)
Update: Actually, I just went into my IDE and typed this.navCtrl.
, and my IDE just showed a pop
, popToRoot
, and popTo
function o.o so maybe it is available but I don't see it in the docs, I'll try it out now.
I believe that for most cases you can use Events.
All you have to do is to subscribe to an event on the parent page and then publish the event with the data you want from the child.
I implemented a variation of the @arlowhite suggestion https://github.com/driftyco/ionic/issues/5724#issuecomment-221691471
He expects pop to transition back to the previous page. This can prevent some possible problems..
Parent
new Promise((resolve, reject) => {
this.nav.push(ChildPage, {resolve: resolve});
}).then(data => {
// process data
});
Child
this.nav.pop().then(() => this.params.get('resolve')('some data'))
Hello everyone! Thanks for the feature request. I'm going to move this issue over to our internal list of feature requests for evaluation. We are continually prioritizing all requests that we receive with outstanding issues. We are extremely grateful for your feedback, but it may not always be our next priority. I'll copy the issue back to this repository when we have begun implementation. Thanks!
This issue was moved to driftyco/ionic-feature-requests#151
Dead link?
driftyco/ionic-feature-requests#151
+1
This feature needs to be in the framework, it's very needed. +1
I use this solution and it works: https://forum.ionicframework.com/t/solved-ionic2-navcontroller-pop-with-params/58104/8.
+1
Why won't you just do this:
this.navCtrl.getPrevious().data.myNewKey = someData;
this.navCtrl.pop();
And in parent Ctrl
public ionViewWillEnter() {
this.myNewData = this.navParams.get('myNewKey')|| null;
}
Parent
ionViewWillEnter() {
this.myData = this.navParams.get('myDataKey') || null;
}
Child
ionViewWillLeave() {
this.navCtrl.getPrevious().data.myDataKey = this.myData;
}
How about this one.
I use it in working project:
Parent
```javascript
let pageClosed= (retData)=>{
console.log('this came back:', retData);
//Do something
}
this.navCtrl.push(ServiceNewPage, {pageClosed: pageClosed});
````
Child
```javascript
ionViewWillLeave() {
var callback = this.navParams.get('pageClosed');
if (typeof callback =='function')
callback("THIS DATA WAS RETURNED FROM THE CHILD PAGE!");
}
````
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Most helpful comment
Why won't you just do this:
And in parent Ctrl