Using Promise.resolve(). then() correctly Error: Uncaught (in Promise): Typeerror: Cannot read Property

Asked

Viewed 2,802 times

0

Hi, I have the following code:


export class Page {
  constructor(public modalController: ModalController) { }

  private async openModal(value) {    
    const modal = await this.modalController.create({
      component: AnotherPage,
      componentProps: {
        "paramID": 123,
        "paramTitle": "Test Title",
        "takenPhoto": "null"
      }
    });

    return await modal.present();
  }

  public async takePicture() {
    this.openModel(null); // aqui dá certo
    Promise.resolve(this.someMethod()).then(this.openModal); // aqui dá erro
  }

}

In the method takePicture i want to open a modal after running the Promise.resolve. In the first execution of the function everything works well, but in the second gives error.

That is the mistake:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'modalController' of undefined
TypeError: Cannot read property 'modalController' of undefined
    at tab2.page.ts:25
    at Generator.next (<anonymous>)
    at tslib.es6.js:73
    at new ZoneAwarePromise (zone-evergreen.js:876)
    at Module.__awaiter (tslib.es6.js:69)
    at openModal (tab2.page.ts:22)
    at ZoneDelegate.invoke (zone-evergreen.js:359)
    at Object.onInvoke (core.js:34201)
    at ZoneDelegate.invoke (zone-evergreen.js:358)
    at Zone.run (zone-evergreen.js:124)
    at resolvePromise (zone-evergreen.js:797)
    at resolvePromise (zone-evergreen.js:754)
    at zone-evergreen.js:858
    at ZoneDelegate.invokeTask (zone-evergreen.js:391)
    at Object.onInvokeTask (core.js:34182)
    at ZoneDelegate.invokeTask (zone-evergreen.js:390)
    at Zone.runTask (zone-evergreen.js:168)
    at drainMicroTaskQueue (zone-evergreen.js:559)

Anyone know how to handle it? Thank you.

1 answer

0

This is a problem with the context of this. this refers to the object in which the method is executed, not to the object in which the method is declared.

If your method openModal is passed as a parameter to be executed in some other context, this will refer to that other context, and not to the context of its object Page. That’s why he can’t find the property modalController, because this property does not exist in this other context.

The easiest way around this problem is by passing a arrow function as parameter, because with this type of function is not made the Binding of the this, that is, the value of this will not be changed to the other context.

Take the example:

class Foo {
  resolvePromise() {
    Promise.resolve().then(function() {
      console.log('Em Foo, this dentro da Promise se refere a:', this) // undefined
    })
  }
}

class Bar {
  resolvePromise() {
    Promise.resolve().then(() => {
      console.log('Em Bar, this dentro da Promise se refere a:', this) // bar
    })
  }
}

const foo = new Foo()
const bar = new Bar()

foo.resolvePromise()
bar.resolvePromise()

So for your problem, use:

Promise.resolve(this.someMethod()).then(() => this.openModal());

Browser other questions tagged

You are not signed in. Login or sign up in order to post.