26

I have 2 pages Page1 and Page2. I have used this.nav.pop() in Page2 and it will pop the Page2 and Page1 will enable but i want to refresh the Page1. Thank you in advance.

4
  • this.nav.pop() used for ? Commented Mar 31, 2016 at 6:36
  • this.nav.pop() is used to pop Page2
    – Akash Rao
    Commented Mar 31, 2016 at 6:51
  • @AkashRao are you after refreshing the entire page or just data in the page? The reason I ask is that angular 2 has put a lot of work into only updating DOM that when it needs to be updated and refreshing the entire page may be overkill depending on what you are trying to achieve.
    – Phil D.
    Commented Jun 5, 2016 at 6:34
  • 1
    There was a solution here where onPageWillEnter is called when you reenter the page allowing you to refresh your data. Hope this helps.
    – Phil D.
    Commented Jun 5, 2016 at 6:50

14 Answers 14

29

you could pass the parent page along with the nav push. that way you could accces the parent page as a navParamter.
in parent page:

 goToChildPage() {
    this.navCtrl.push(ChildPage, { "parentPage": this });
 }

and in the child page before pop you could call functions on parent page

this.navParams.get("parentPage").someFnToUpdateParent();
  //or
this.navParams.get("parentPage").someFnToRefreshParent();
5
  • Thanks! The best way to solve this problem, congrats! Commented Sep 29, 2017 at 22:52
  • Superb, Thank you! Commented Mar 25, 2018 at 14:15
  • I tried calling a function of the parent page with an argument but it didn't work. Seems like it doesn't pass args. But without argument is working like a charm. BTW I never knew we could call functions on Pages this way. THANKS. Commented Aug 3, 2018 at 10:06
  • This solution is breaking OOPs, subscribe->publish event or through page lifeycycle event ionViewDidEnter should be ideal choice i guess
    – Naga
    Commented Feb 16, 2019 at 17:46
  • @Naga I just tried this. You're right, it does seem to be the ideal choice. This is mentioned as a solution by somebody else below. Commented Feb 18, 2019 at 14:16
19

Ignore the direct angular implementations suggested here, especially since you are using Ionic 2 and the suggestions are assuming Ionic 1. Don't start mixing too much of direct angular in your ionic app unless there is no ionic implementation for what you need. Import "Events" from ionic/angular2 in both Page1 and Page2, then in Page2 do something like

this.events.publish('reloadPage1');
this.nav.pop();

And in Page1 put

this.events.subscribe('reloadPage1',() => {
 this.nav.pop();
 this.nav.push(Page1);
});
2
  • 3
    this works but it doesn't look good to have the UI flash back a page from Page1 and then go forward again to page1
    – Avner
    Commented Apr 5, 2017 at 0:10
  • 1
    This is a good solution but the pop, push in the subscribe is not. Instead you could have an initializer function within Page1 that you could call in the subscribe. Commented May 4, 2018 at 12:26
17

You may want to implement one of these in your page:

ionViewWillEnter ionViewDidEnter

Please review the navController and page lifecycle documentation: http://ionicframework.com/docs/v2/api/components/nav/NavController/

2
  • 8
    ionViewWillEnter ionViewDidEnter doesn't work when 'poping' (back button) so I think this is not a good option
    – gtamborero
    Commented Apr 21, 2017 at 23:05
  • ionViewWillEnter worked pushing and popping thanks alot
    – TeT Psy
    Commented Dec 5, 2017 at 19:39
13

Simple solution that worked for me was calling the get service method again in ionViewDidEnter

ionViewDidEnter() {
    this.loadGetService();
}
1
  • 1
    Good solution. Though ionViewDidEnter need not return anything. It is a void. Commented Sep 14, 2017 at 14:50
6

On PAGE 1:

import { Events } from 'ionic-angular'
constructor(public events:Events){
   this.listenEvents();
}
... ...
listenEvents(){
   this.events.subscribe('reloadDetails',() => {
    //call methods to refresh content
   });
}

On PAGE 2:

import { Events } from 'ionic-angular'
constructor(public events:Events, public navCtrl:NavController){
}

function(){
   this.events.publish('reloadDetails');
   this.navCtrl.pop();
}
3

You may consider send an event before call this.nav.pop to let page 1 reload itself.

2
  • hi gucheen, can you please show me a sample code to call an event before pop .
    – Akash Rao
    Commented Mar 31, 2016 at 7:20
  • Just as in Angular, use $emit in page 2 and $on in page 1
    – gucheen
    Commented Apr 1, 2016 at 3:24
2

Like Jonathan said, you can import Events from ionic-angular, but you don't need push and pop again, call your methods to reload only the content.

In page2:

this.events.publish('reloadDetails');
this.navCtrl.pop();

In page1:

this.events.subscribe('reloadDetails',() => {
    //call methods to refresh content
});

That works for me.

0
2

I simply load the details in page 1 in an ionViewWillEnter function (using Ionic 2). This handles both the initial load and any refresh when popping back to page 1.

Documentation is here.

ionViewWillEnter
"Runs when the page is about to enter and become the active page."

1

I found this technique to reload a page:

this.navCtrl.insert(1, MyPage);
this.navCtrl.pop();
3
  • Yo and where the hell you get your parameters back from? And what are you doing if you have computed parameters that you want to use again? Youor answer is not a solution, and nobody should every use this code for what he asked! Commented Apr 18, 2017 at 14:14
  • I think the best solution is to make a copy of the received parameters and to reinject them into the "insert" (this.navCtrl.insert(1, MyPage, paramsCopy});).
    – SiteXw
    Commented Apr 19, 2017 at 14:43
  • I think its still not usable in most situations and you require the entire controller to be initaized again. Commented Apr 19, 2017 at 18:25
1

I had the same problem and spend many hours searching and trying the solution.

If I understand, your problem is:

Page 1 have some bindings that you get from an API / Webservice.

Page 2 have some inputs and when pushing the back button (pop) you want to SAVE data + refresh the Page 1 bindings.

The way I solved it has been reading a post on StackOverflow that now I can't find :( !!

The solution is using an Injectable Service.

PAGE 1:

/* IMPORTS */

import { App, Nav, NavParams } from 'ionic-angular';
import { Oportunidades } from '../../services/oportunidades.service';

/* SOME BINDINGS HERE */ 
{{oportunidades.mesActual.num_testdrive}}

/* CONSTRUCTOR */
  constructor(
    private oportunidades: Oportunidades, // my injectable service!
    public app: App,
    public nav: Nav,
    public params: NavParams
  ) {

// Call to the Injectable Service (named oportunidades):
    this.oportunidades.getOportunidades();
  }

INJECTABLE SERVICE:

/* IMPORTS */ 
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class Oportunidades {

  public url = 'http://your-API.URL';
  public data: Observable<Object>;
  public mesActual: Object = [];

  constructor(private http: Http){
    //GET API DATA
    this.data = http.get(this.url).map(res => res.json());
  }

  getOportunidades() {
    this.data.subscribe(data => {
      this.mesActual = new MesActual(
        data["mes_actual_slide"].num_testdrive,
        ...
        //Here I get the API data and set it on my injectable object
      );
    });
  }
}

PAGE 2:

/* SOME IMPORTS */
import { NavController } from 'ionic-angular';
import { UserData } from '../../services/data.service';
import { Oportunidades } from '../../services/oportunidades.service';
import { Http, Headers, URLSearchParams } from '@angular/http';

/* SOME example BINDINGS and INPUTS: */
@Component({
  template: `
  {{ day[selectedDay].dia }}
    Input data: 
    <ion-input type="number" clearOnEdit="true"
      #ventas id="ventas" value={{day[selectedDay].ventas}}
      (keyup)="setVal(ventas.value, $event)">
    </ion-input>
  `,
  providers: [
  ]
})

export class PageInsert {

  constructor(
    public navCtrl: NavController,
    private http: Http,
    private userData: UserData,
    public oportunidades: Oportunidades // my injectable service!
  ) {

    send(selectedDay){
      var url = 'http://your.api.url/senddata';

      // I SAVE data TO API / Webservice
      this.http.post(url, params, { headers: headers })
      .map(res => res.json())
      .subscribe(
        data => { 
          console.log(data); 
          // Here i'll call to the Injectable service so It refresh's the new data on Page1 
         // in my case, this send function is called when "pop" or "back" button of ionic2 is pressed
         // This means: On click on back button -> Save and refresh data of the Injectable that is binded with the Page1
          this.oportunidades.getOportunidades(); 
          return true; },
        error => { 
          console.error("Error saving!"); 
        }
       );
    }
}

I hope it can help you!! Ask for any similar problems :)

1

I spent a day and a half on a similar issue. The solution is anti-climatic really.

I'm passing a FormGroup from Page-1 to Page-2. I update the FormGroup values in Page-2. When I pop Page-2, Page-1's form is not updated with the new values. It hasn't been watching for changes.

To fix this, I patch the FormGroup with itself after Page-2 has been popped but still in the Page-2 component.

This is more responsive, but requires a direct call to close().

// Page-2 close method
public close(): void {
    this.navCtrl.pop();
    this.formGroup.patchValue(this.formGroup.value);
}

This is all encompassing, but I do see the refresh on Page-1.

// Page-2 nav controller page event method
ionViewWillUnload() {
    this.formGroup.patchValue(this.formGroup.value);
}
1

In some situations instead of pop() you can use the push() function. When you enter the page with the push() function it is reloaded. Also you can remove page2 from the navigation.

 this.navCtrl.push(TabsPage).then(() => {
   const index = this.viewCtrl.index;
   this.navCtrl.remove(index);
   });

Or if you have more than one page for example page1->page2->pag3:

this.navCtrl.push(TabsPage).then(() => {
const index = this.viewCtrl.index;
this.navCtrl.remove(index, 2); //this will remove page3 and page2
});
0
ionViewWillEnter() {
    this.refresh();
}

ionViewWillEnter will be called just before any time you (re)visualize the page

-1

Please checkout my solution, which I've posted here:

Maybe you can adapt it to your needs.

The main point of my intention was to prevent, passing a whole module with this as a navCtrlParam into the push()'ed page, like it was mentioned in some comments before.

Hope it helps!

Cheers
Unkn0wn0x

Not the answer you're looking for? Browse other questions tagged or ask your own question.