How to use modal non-async

#1

So how do I use a modal non-asynchronously. You know, like how a normal person would use it? I can’t even wrap my head around why you would want a data capture modal to behave asynchronously.

So here’s what I’m trying to do:

async presentModal() {
        const modal = await this.modalController.create({
            component: NameComponent,
            componentProps: { value: 123 }
        });
        await modal.present();
        await modal.onDidDismiss();
    }

    public respond(response: Response) {
        this.parse(response.text);
        ...

I want to get the return from the modal before proceeding with processing of respond(). I even tried making respond itself async and doing await this.parse(response.text) but it didn’t bother to ‘await’ the call to parse and just kept going

#2

Hello,

hmm I am not sure if I understand you right, so here is my guess.
You have a page and want show a modal.

async presentModal() {
        const modal = await this.modalController.create({
            component: NameComponent,
            componentProps: { value: 123 }
        });
        await modal.present();
    }

So I think you do something in your NameComponent and want to get datas back to your page.

So you call, for example on a button click in your NameComponent, to your injected ModalController

modalController.dismiss({
  'result': value
})

This will close your modal and returns an object with member result containing value.

If you want to do something with returning object in your page, who created the modal,you extend your code to

async presentModal() {
        const modal = await this.modalController.create({
            component: NameComponent,
            componentProps: { value: 123 }
        });
        await modal.present();
        const { data } = await modal.onDidDismiss();
//todo something with your data 
this.respond(data)
    }

OnDidDissmiss should be a promise so you can also use promise syntax.

I do not like promise syntax nor async await syntax, but it forces people writing non blocking code

Best regards, anna-liebt

#3

Yeah, I’m pretty much using the example code.

But no, this doesn’t solve my issue. I don’t just need to do something with the returned result. I need to completely stop the program functioning until the result comes back, which is the specific use-case for a modal dialog.

Basically I have several action buttons, all of which have a line of text that’s showed when clicked, but can also trigger an action which should happen before the text is shown. One of those actions is to show a modal to capture the user name.

So the flow should be:
click action button
show modal
enter data and close modal
show action text

the rest of my respond function is what shows the action text, but it’s not waiting for the data capture modal to come back.

“forces people writing non blocking code”. Blocking code is what I want. I can’t believe they would completely remove the ability to write a synchronous flowing program. It’s madness.

#4

Hello,

click action button
show modal
enter data and close modal
show action text

hmm its late, maybe I do not see it, but none of them is showing your code. Otherwise my english is not really good.

async presentModal() {
        const modal = await this.modalController.create({
            component: NameComponent,
            componentProps: { value: 123 }
        });
        await modal.present();
        const { data } = await modal.onDidDismiss();
//todo something with your data 
this.respond(data)
    }

Above code waits till creating of modal is finished. The NameComponet could be a complex and time-consuming component. Without await I will execute the next line, maybe before the modal is ready. The next line shows the modal and waits as long the modal will call .dismiss inside the modal. The underlaying ui is blocked for user inputs as long the modal is shown, but not blocked for executing code.
await modal.OnDidDismiss waits as long as it needs to return the data. After that you can do with your data whatever you want.

Best regards, anna-liebt

#5

Yeah, you’re missing what the code is doing, but I also left out a function that might make it more clear. this.respond(data) isn’t called from presentModal(), it’s what calls it and then needs to proceed to do other things after the modal is done. Note that in this version I’m not actually doing anything with the modal response yet, just trying to get it to function in the proper sequence before I move on to that.

// Show my modal
async presentModal() {
   const modal = await this.modalController.create({
      component: NameComponent,
      componentProps: { value: 123 }
   });
   await modal.present();
   return await modal.onDidDismiss();
}

// Parse the action response to see if we need to show the modal
public parse(t: string) {
   if (t.indexOf("<NAMEENTRY>") >= 0) {
      this.presentModal();
   }
}

//Handle the action button click
public respond(response: Response) {
   //Check the response text to see if we need a modal or any other future actions
   this.parse(response.text);
   //proceed to display the response text, after modal has been completed if presented
   this.display = response.text //or something like that to put the text on the screen
}
#6

Hello,
first: Oh God, please don’t let me make a fool of myself, because I do not like promises and async/await and js/ts is so evil.

You click on a button, that will call syncronously public respond(response: Response), which call syncronously this.parse(response.text), which call this.presentModal(), but this is a asyncrounous function.

public respond gives the controll ( and do nothing as long it gets the controll back) to this.parse(response.text). This gives the controll to the if, inside if it gives the controll to this present modal(), but this is async (it is doing something, but gives immedatly the controll back, because that means asyncronous executing), if gives the controll back, parse gives the controll back, inside respond the next code line will execute this.display = response.text, independent what async presentModal() is doing.

If you need to wait that a async function is completed, then you need to await it. await needs wraped inside async function, if you need to await this async function, you need …

That is why await can not used on top level.

I hope your code is a demostration, because it makes (imho) no real sense.

Oh lord, please…

Best regrads, anna-liebt

#7

Nope, definitely not a demonstration. Building a game engine and what I have is the way it should be written. You have actions that are defined in a config file, which are able to trigger various events. You have a method that processes the action (respond() and parse()) and triggers any necessary actions (presentModal()). Since everything is defined in config you need the methods to be generalized handlers, executing as many events in sequence as required by the action.

I’ve been programming for 30 years across multiple industries and I’ve never in my life seen a need for an asynchronous modal. It completely defeats the purpose of what a modal control is, which is to block all other program input until the modal is complete. When you do a sign up modal, you obviously don’t want the rest of the program to process until you get the sign in details back. The only difference here is that instead of a specific-use method like a sign in, you have a generic use-method. Yes, you can hack the asynchronous sign in modal to function like it’s synchronous, which is what all the example code is, but it’s just that, a hack.

And that’s what I’m going to have to do, hack it. I’ve figured out how I need to reorganize it but it’s ugly and definitely not elegant design. There’s going to be code reuse and unnecessary method execution. I simply do not understand why it HAS to be async.

#8

Basically what I have to do is instead of having the button click call respond(), it has to call parse(), and then parse() is changed to:

    async parse(response: Response) {
        if (response.text.indexOf("<NAMEENTRY>") >= 0) {
            await this.presentModal();
            this.respond(response);
        } else {
            this.respond(response);
        }
    }

Absolutely not the way it should be done since it’s not DRY but the only way to make it work if we’re being forced into async. Basically what they’ve done is made it so everything has to be async and you’re just hacking it to look synchronous.