[SOLVED] Ionic navController pop with params

I think the same general skeleton should work perfectly for you.

export class AuthedHttp {
  constructor(private _sink: Sink, private _http: Http) {
  }

  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    let allopts = this._frotzOptions(url, options);
    return this._http.post(url, body, allopts);
  }

  private _frotzOptions(urlo: string | Request, options: RequestOptionsArgs): RequestOptionsArgs {
    if (!options) {
      options = {}
    }
    if (!options.headers) {
      options.headers = new Headers();
    }
    let token = this._sink.getToken();
    // add it to options.headers
    return options;
  }
}
export class TypicalPage {
  constructor(private _ahttp: AuthedHttp) {
  }

  foo() {
    this._ahttp.post('restricted-url', body).subscribe((rsp) => {
    });
  }
}

Not a NavParam in sight.

2 Likes

Cool, thanks! I’ll run some tests locally to see if I can get this integrated without using any annoying navParams.

May G-d bless you man! It worked fine, you are a genius, I hope someday have the knowledge you have. Thanks a lot!

Works like charming. Save my time.Thanks bro

Hi, may i know how did you do it?
i assigned _params to my local variable, however it shows undefined when i use ionViewDidEnter to console the local variable.
Can you help me ?

2 Likes

@aaronksaunders Thanks for solution.

Needed a slight tweak

    let _that = this;
    this.callback = function(_params) {
        return new Promise( (resolve,reject) => { 
                                    console.log('In callback:', _params);
                                    _that.credentials = _params;
                                    resolve(); 
                                                }
                            );
    }

Please don’t emulate the previous post. It packs several antipatterns into a fairly small space.

Great! Thank you so much.

Wow, Sneaky love it!!

I achieved similar functionality using Events listeners using following codes -

MainPage-

import { NavController, Events } from 'ionic-angular';
import { OtherPage } from '../other/other';

export class MainPage{
    constructor(private navCtrl: NavController,
                private events: Events) { }
    
    private pushOtherPage(){
        this.events.subscribe('custom-user-events', (paramsVar) => {
            /// Do stuff with "paramsVar"

            this.events.unsubscribe('custom-user-events'); // unsubscribe this event
        })

        this.navCtrl.push(OtherPage); // Push your "OtherPage"
    }
}

OtherPage-

export class OtherPage {
    /// Under some function
    this.navCtrl.pop().then(() => {
        /// Trigger custom event and pass data to be send back
        this.events.publish('custom-user-events', myCustomParams);
    });
}
4 Likes

NavController’s pop method already returns a promise which is resolved when the transition has completed. The following approach is based on that fact and it is different from the accepted answer, but works in a similar way:

Main page

export class MainPage {
  dataFromOtherPage = null;

  callback = data => {
    this.dataFromOtherPage = data;
    console.log('data received from other page', this.dataFromOtherPage);
  };

  constructor(public navCtrl: NavController) {}

  openOtherPage() {
    this.navCtrl.push('OtherPage', {
      callback: this.callback
    });
  }
}

The other page:

export class OtherPage {
  constructor(public navCtrl: NavController, public navParams: NavParams) {}

  goToPreviousPage() {
    this.navCtrl.pop().then(() => {
      this.navParams.get('callback')('This is some data');
    });
  }
}

8 Likes

Thank you!
But for others, I must say that you need to
bind ‘this’ to the callback function.
Otherwise '‘this’ will be the other page model,
no the expected one.

Store values in storage and use ionViewDidEnter in your previous page

ionViewDidEnter(){
//get params here
}

thanks EmreErdogan, simple and clear example

You could use the navCtrl.getPrevious() method to set the data from your Page2 and send it to Page1.

You need to use the ionWillLeave() method in Page2 and ionViewWillEnter() method in Page1 in order to achieve this.

Example

Page where we pop (Page2.ts)

public ionViewWillLeave(){
  this.navCtrl.getPrevious().data.yourVar = "yourValue"
}

Page after pop() (Page1.ts)

public ionViewWillEnter(){
  this.yourVar = this.navParams.get("yourVar");
  console.log(this.yourVar); // ==> "yourValue"
}

I saw this answer in StackOverflow and it helped me out

2 Likes

I really dislike the suggestion in the previous post. It encourages overly tight coupling between pages, which makes apps hard to read, hard to test, hard to maintain. If you need to share data amongst pages, use a service provider. That way the relationship between each page and the service is clearly delineated. Poking around in framework navigation internals is a bad idea.

Is there any way that can be use in ionic 4 ?

you can check and resolve your problem

The solution is very easy. Just follow the standard component interaction pattern set by Angular. Here is some code:

ion-nav.service.ts
-To save the IonNav instance. It’s used the same way as NavController in Ionic 4.

@Injectable()
export class IonNavService {
    
    public ionNav: IonNav;

    public setIonNav(ionNav: IonNav): void {
        this.ionNav = ionNav;
    }
}

ion-nav.component.ts
-Root component for using IonNav and setting the instance in the service.

@Component({
  selector: 'app-ion-nav',
  template: `<ion-nav #nav [root]="root" [rootParams]="rootParams" animated="true" swipeGesture="true"></ion-nav>`
})
export class IonNavComponent implements AfterViewInit, OnInit {

  @Input() root : Type<any>;
  @Input() rootParams: any;
  @ViewChild('nav', { static: false }) ionNav : IonNav;

  constructor(private ionNavService: IonNavService) {}

    public address : Address;
    public onAddressSelect    : EventEmitter<Address> = new EventEmitter<Address>();
    public onAddressUpdate    : EventEmitter<Address> = new EventEmitter<Address>();

  ngOnInit():void{
    this.onShippingAddressSelect.subscribe(address=> /* logic */ );
    this.onShippingAddressUpdate.subscribe(address => /* logic */ ); // dont forget to unsubscribe 

    //e.g. how you can pass variables.
    this.root = AddressListPage;
    this.rootParams = {
        address: this.address,
        onAddressSelect: this.onAddressSelect,
        onAddressUpdate: this.onAddressUpdate
    }
  }
  ngAfterViewInit(): void {
    this.ionNavService.setIonNav(this.ionNav);
  }

}

address-list.component.ts
-Example component set as root in previous code and params were passed through rootParams

@Component({
  selector: 'app-address-list',
  template: `
  <ion-content>
    <ion-button (click)="select(address)">select</ion-buttons>
    <ion-button (click)="edit(address)">select</ion-buttons>
  </ion-content>
  `
})
export class AddressListPage {

  constructor(private _ionNavService: IonNavService) { }

  @Input()  address : Address;
  @Output() onAddressSelect    : EventEmitter<Address> = new EventEmitter<Address>();
  @Output() onAddressUpdate    : EventEmitter<Address> = new EventEmitter<Address>();

  // Pass values back
  select(address: Address){
    this.onAddressSelect.emit(address);
  }


  edit(): void {
    this._ionNavService.ionNav.push(AddressEditPage, { address: address, onAddressUpdate: this.onAddressUpdate });
  }

}

address-edit.component.ts
-Second component on IonNav stack. Pushed in address-list params were passed through Push

@Component({
  selector: 'app-address-edit',
  template: `
  <ion-content>
    <ion-button (click)="save()">Save</ion-buttons>
  </ion-content>
  `
})
export class AddressEditPage {

  constructor(private _ionNavService: IonNavService) { }

   @Input()  address            : Address;
   @Output() onAddressUpdate    : EventEmitter<Address> = new EventEmitter<Address>();

  // pass values and go back
  save() {
    this.onAddressUpdate.emit(this.address): 
    this._ionNavService.ionNav.pop();
  }

}