How to return a promise from tab select?


#1

Can you show me how to make a promise out the tab select method so before I emit an event I ensure the target page at the new tab has loaded (ie. its ionViewDidLoad fired). I need to ensure the target page has had a chance to subscribe to the event. Something equivalent to when .select used to return a promise.

this.NavController.parent.select(TargetTabIndex).then(()=> {
        this.Events.publish("Play");
});

You can provide similar with async/await, I will take whatever you hand me :slight_smile:
You can assume a shared service between the page1 at tab1 making the .select and target page2 at tab2.

Note: I am dealing with a non-blocking .select(0 method which unlike for example, setTimeout does not have a callback to resolve the promise. Thus, I don’t know how to return a promise based on the target page ionViewDidLoad() event firing.
Do I need to sleep/loop and check for a flag set via ionViewDidLoad() to resolve the promise? This idea looks terrible, at the moment.

Thank you.


#2

here is an example

public exampleFunction():Promise<string>{
return new Promise((resolve,reject)=>{
// your whatever code here
// if everything went well 
reolve('everything went well');
//if something went wrong or had an undesirable result
reject('something bad happened');  
});
}

how to use it

1-in a normal function

exampleFunction().then(data=>{
// data, is what have been resolved, in this case it would have 'everything went well'
}).catch(error=>{
// error will have the reject data, in this case it would have 'something bad happened'
});

2- inside an async function using await

let data = await exampleFunction();
// in case of resolve data should contain 'everything went well'
// in case of reject honestly i do not know since i have not tried it, but i guess it would return  'something bad happened'

#3

Not that anything @MarcusIII is saying is technically wrong, but there are extremely few occasions where one needs to be explicitly instantiating a Promise in an Ionic app. Certainly there are thousands more code samples on the web perpetuating that idiom than there are actual situations where it’s justified.


#4

So I have written Promises before to establish a sequential process and they seem to work, something like the following:

private SlidePostPause() {
    console.log("AMSController------------>>SlidePostPause", this.AMSData.SlidePostPause);
    return new Promise((resolve) => {
      this.timer1 = setTimeout(resolve, this.AMSData.SlidePostPause * 1000);
    });
  }

However, in the post I am dealing with a non-blocking .select() method which unlike the setTimeout does not have a callback to resolve the promise. Thus, I don’t know how to return a promise based on some target page ionViewDidLoad() event. Could you please be more explicit and share some code snippets.

I have read thru several tutorials/blogs about promises, chains of them etc… But all this lingo is just as annoying as the one spewed by Microsoft (don’t mean to compare) Really, I could careless if it is async/await, promises, or love-letters. At the end of the day/night, I want to tell this ion-tab switch, let me know you are ready because now I am sending you a message. Voila!

At the moment I have a mind-block and can’t proceed over several snags I need to bulldoze, as usual your knowledge and assistance is greatly appreciated…
Thank you.


#5

In the resolve portion of the code, how do I ?wait? for the target page to load? via a loop and setTimeout construct polling on some service.flag ? Sounds awful. Thanks.


#6

to make sure that i understand what you are trying to do is
you have page 1 and page 2 and when page 2 is fully loaded tell page 1 that it is loaded right ?
when it’s loaded (page 2) you want to run some code in page 1…
in that case you don’t need a Promise.
and i agree with @rapropos there is few occasions where you need a promise and yours isn’t one.


seems to me what you need is an event published from page 2
that page 1 listens to


#7

If you are using container like tabs and you need to send events from inside to an other one, it might be good to use some sort of react Observable or Subject. So with the page argument (NavParams) just send the Observable and subscribe or call next in other time. If you use eventEmitter, the only way i was able to do it to call the tab onChange from the code with the parameter what i would have liked.


#8

I think you got the pages right but I will iterate with my own words, page 1 is hosted in tab1 and page2 in tab2. Page1 is doing the following if there are on some URL parameters present

        this.NavController.parent.select(1);
        setTimeout(() => {
                        // INOTE: use ionic2 events to comm. from page to page
                        this.Events.publish("PlayersView:PlayAnyVideo");
        }, 1000);

Page2 has the following in the constructor

        // 20170430
        this.Events.subscribe('PlayersView:PlayAnyVideo', () => {
            console.log('PlayersView<<e------------PlayersView:PlayAnyVideo');
            this.PlayAnyVideo();
        });

Unlike push/pop, this.NavController.parent.select quit returning a promise back in some beta, so I am fudging some delay. There is an open bug report about .select by @mhartington himself https://github.com/driftyco/ionic/issues/8662

Because page2 is slow the first time, loading and initializing one of several players, it will miss this particular event, the first time. As you can see I am broadcasting an event to Page2 however it will miss it 30% of the time via this poor/unreliable construct.

Note: Once my main Pages in tabs are loaded, I do not want them to die and get recreated. That’s the reason I have stayed away from NavController.push/setRoot…, except for popping up a user preference page or such.

Perhaps, my poor understanding of Promises, leads me to believe they are appropriate here
to ensure that one thing happened .then do another, .then do another. (force/ensure a sequential execution, the fact that JS is single threaded vs other multi-threaded environment will remain beyond my domain. I accept to think most methods these days are non-block (async) by nature. I need a relatively simple construct/pattern to apply here and ti works) I see another reply again mentioning observables/subject please show me a snippet and I will apply it.

Going back to my simply wired mind, Page2 could set a .Ready flag true via a shared service also injected in Page1 but how to watch for it, the TS/Ion/Angular way, is still very blurred to me.

Thank you for trying to help.