Home > Software engineering >  Passing a function as a parameter in typescript
Passing a function as a parameter in typescript

Time:02-22

I'm coding with Ionic/Angular.

I want to pass a function as a parameter to a function in another file, but the function doesn't get called.

alert.service.ts

  showAlertWithAction(header: string, message: string, action: () => void) {
    const alert = this.alertController.create({
      cssClass: 'custom-alert-ok',
      backdropDismiss: false,
      message,
      header,
      buttons: [{
        text: 'Okay',
        handler: () => action()
      }]
    });
    alert.then(createdAlert => createdAlert.present());
  }

The function gets called in another file:

some.page.ts

this.alertService.showAlertWithAction("Hello!", "Press Okay to close the modal", () => { this.closeModal() })
async closeModal() {
  await this.modalController.dismiss()
}

CodePudding user response:

A few things to check:

  1. Does closeModal() really need to be async? I imagine that this.modalController.dismiss() returns a promise, but you don't appear to need anything from that promise's return value (i.e. no .then()), so your function could look like this and still close your modal:

    closeModal(): void {
      this.modalController.dismiss()
    }
    
  2. If point 1 is implemented, then closeModal becomes a function of the shape () => void. This is the same shape you wanted to pass to your action argument. The correct way to do this would be

    this.alertService.showAlertWithAction(
      "Hello!", "Press Okay to close the modal",
      this.closeModal  // Note: Do not include the brackets, this is now a function reference
    )
    
  3. If you want to pass a function from one file to another, often you want to execute that function "with all the data from the original file". In other words you want to preserve that functions "execution context".

    For example, this.modalController is likely an instance of a service (or some other dependency) that is being passed into some.page.ts. When you pass closeModal() into another file, what you're really saying is "call .dismiss() on the instance of modalController that my some.page.ts had access to.

    In this case, we want the additional step of binding some.page.ts's execution context to our method before passing it on:

    this.alertService.showAlertWithAction(
      "Hello!", "Press Okay to close the modal",
      this.closeModal.bind(this)
    )
    

Assuming all of the logic in your alert component is calling the handler method on your buttons correctly, the passed in method should now fire

  • Related