Использование Promise.resolve (). Then () правильно Ошибка: Uncaught (в обещании): TypeError: Невозможно прочитать свойство - PullRequest
0 голосов
/ 13 января 2020

У меня есть этот код:


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); // here's OK
    Promise.resolve(this.someMethod()).then(this.openModal); // ERROR!!
  }

}

По методу takePicture Я хочу открыть модал после выполнения Promise.resolve. На первом выполнении все ок, но на втором у меня ошибка.

ОШИБКА:

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)

Ответы [ 3 ]

1 голос
/ 13 января 2020

Почему происходит ошибка? Это потому, что если вы хотите вызвать 'this' внутри неявного вызова функции, вы должны связать с этим вызовом состояние 'this'. Проверьте это:

До:

  public async takePicture() {
    this.openModel(null); // here's OK
    Promise.resolve(this.someMethod()).then(this.openModal); // ERROR!!
  }

После:

  public async takePicture() {
    this.openModel(null); // here's OK
    Promise.resolve(this.someMethod()).then(this.openModal.bind(this)); // JUST FINE :)
  }

Сейчас неявный вызов получит это состояние для правильного использования здесь:

await this.modalController.create({...

Предварительная инструкция для pt-BR pode mandar msg:)

1 голос
/ 13 января 2020
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 modal.present();
  }

  public async takePicture() {
    await this.openModel(null); // Need to await a promise
    const data = await this.someMethod()
    await this.openModal(data);
  }

}
0 голосов
/ 13 января 2020

В соответствии с тем, что говорит @VLAZ (я предлагаю прочитать ссылку, которую он предоставляет), вы предполагаете, что this в контексте функции openModal () ссылается на контекст класса. Поскольку значение this зависит только от того, «как» вызывается функция, то появление this в this.modalController еще не связано с контекстом, поэтому this оказывается неопределенным, и это является причиной Вы получаете сообщение об ошибке.

Вы можете установить this в контекст класса перед вызовом функции. Вот несколько способов:

1 - связать this в конструкторе

constructor(public modalController: ModalController) {
    this.openModal = this.openModal.bind(this);
}

2 - использовать функцию стрелки, которая автоматически связывает this к контексту класса (родительскому контексту).

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

     return modal.present();
}

Я думаю, что есть другие способы сделать это, но они широко приняты. Надеюсь, это поможет!

...