Как настроить кнопку отправки формы, привязанную к вызову службы, который должен завершиться до отправки в Angular/TypeScript?

#javascript #angular #typescript #async-await

Вопрос:

Я пытаюсь настроить отправку формы, в которой сама форма содержит поле, которое используется в другом месте приложения и, следовательно, к нему привязана собственная служба. То, что я собираюсь сделать, — это настроить кнопку «Отправить» для формы, чтобы выполнить вызов службы для этого конкретного поля, дождаться, пока он завершится успешным ответом, а затем перейти к обычной логике отправки формы.

Вот упрощенная версия того, что я пробовал до сих пор:

 async onSubmit(form) {
    if(specialField) {
        const response = await this.updateSpecialField();
    }
    // I will leave the rest of the form submission abstracted away
}

async updateSpecialField() {
    this.specialService.updateField().subscribe(then => {
        this.specialService.loadingFields$.subscribe(data => {
            this.loading = data;
        });
    });
}
 

В этом случае вызов службы выполняется, но он происходит в фоновом режиме и всегда завершается после отправки формы. Поскольку мне не повезло с этим маршрутом, я попытался использовать ожидание и обещает завершить вызов службы, прежде чем продолжить.

Вот другой подход к той же функции updateSpecialField:

 async updateSpecialField() {
    let updatedFieldResponse = await this.specialService.updateField().toPromise();
    return Promise.resolve(updatedFieldResponse);
}
 

В этом случае строка возврата, похоже, никогда не выполняется, и отправка формы не происходит. Я получаю успешный ответ от службы, но она не возобновляет выполнение строк кода с того места, где я ожидаю.

Ответ №1:

Попробуйте это

 async onSubmit(form) {
    if(specialField) {
        const response = await this.updateSpecialField();
    }
    // I will leave the rest of the form submission abstracted away
  }
  
  async updateSpecialField() {
    return this.specialService.updateField().pipe(
              switchMap((_: any) =>
                this.specialService.loadingFields$.toPromise().then(data => {
                    this.loading = data;
                })
              )
            ).toPromise();
  }