Modal Popup Issue (Please help)

Why in second level page (for example, activity page (first level), activity detail page (SECOND level page)), modal popup not working, only refresh page, then, modal popup can show properly. The first time loading, always failed …

It doesn’t. There’s something in your code that is causing the problem. The ModalController doesn’t care about page 2 or page 200.

1 Like

Thx and I will debug for it.

It sounds as though your data arrives after the page is ready. Maybe you have a Promise or an Observable that has not returned yet before you present the modal. Then when you refresh, the information is available. But maybe something else is happening.

Yup, you are right and I am calling one API and using that API data to compare with previous loaded API and make do some calculation and finally produce a popup to pop out the result. BTW, I am using Observable.

Hi Aaron, have you faced these kind of weird issue before? How you debug and fix it?

It stops being weird once you get more experience with asynchronous calls. You’re probably still writing as though the Observable happens immediately. Imagine modal.present() happens immediately, but the line with your Observable takes 5 seconds. Then if you write

lineWithObservable;
modal.present();

it looks as though the first line happens first and the second line happens second. But what really happens is modal.present() happens immediately, and lineWithObservable happens in 5 seconds.

So if you’re using a Promise, use then, and if you’re using an Observable, use subscribe.

this.myObservable.subscribe(data => { 
                                      store data somehow;
                                      modal.present();
                                    }
                           );

There are other strategies too, but that’s the most common approach.

Here is my code:

Observable
.forkJoin(tasks)
.subscribe(
(assessments: any) => {
loading.dismiss().then(() => {
… …
}
});
},

this.popupAfterSubmit is the function and i am going to call another API and do the calculations, as you can see my code:

popupAfterSubmit(){
const loading = this.loadingCtrl.create({
content: this.loadingMessages
});
loading.present();
this.gameService.getGameItems(this.getCharacterID)
.subscribe(
data => {
console.log("Items: ", data.Items);
… …
loading.dismiss().then(() => {
let itemsPopup = this.modalCtrl.create(ItemsPopupPage, {combined: this.combinedItems, events: this.navParams.get(‘event’)});
console.log("combined object array data: ", this.combinedItems);
itemsPopup.present();
});
},
err => {
loading.dismiss().then(() => {
console.log("Err: ", err);
});
}
);

Your code performs the nested promises antipattern.

DO NOT DO: Promise.then( () => Promise.then => Promise.then())

OK TO DO: Promise.then( _ => Promise).then…

Ok to do one after the other. Not ok to do one inside the other. Also, if you want to chain, it’s better to have all Promises, or all Observables. I’d turn the forkjoin into a Promise with toPromise() and make a chain of all Promises.

but How you handle loading.dismiss().then(),

my understanding based on your suggestions:

I cannot write code in this way:
loading.dismiss().then(() => {
… …
alert.present().then(() => {
this.popupAfterSubmit();
});
});

I need to write my coed in this way?

loading.dismiss().then(() => {
… …
alert.present().then( _ => {

}).then(() => {
this.popupAfterSubmit();
});
});

is that what your mean?

About forkjoin into a Promise with toPromise(), I did some searches, and I found something like this,

Is that this kind of syntax?

return this.http.get(this.publishersUrl)
.toPromise()
.then(response => response.json().data)
.catch(this.handleError);

If you chain Promises, it is much easier to debug your code.

doFirstPromise().then(_ => loading.dismiss() )
                .then(_ => doSecondPromise() )
                .then(_ => doThirdPromise() )
                .then(data => this.createModalWithData(data) );

I would do it something like that. I’d create a private method to create the Modal, and go to that method at the end of the Promise chain. Much easier to read, and to debug if you have an issue.

1 Like

Thx Aaron, and I will try it on my project, and if still not working , can i just use angular way to create a modal and trigger to display my calculation result based on clicking a button, do you think this might be working? I mean this is my last resort …, do you think its feasible to do it?

No. How you create the modal does not matter. When you create the modal matters. Create it after all of your API calls complete.

Cool, thx mate, really helpful, and I will try it.

Please edit your post, it is not very readable at the moment.
Use the </> button above the input field to format your code, command line output or error message (select the text first, then click the button or wrap it in ``` manually). Check the preview if it looks better. This will make sure your text is readable and if it recognizes the programming language it also automatically adds code syntax highlighting. Thanks.

Yup, I will do some changes.