Как сделать асинхронную функцию в угловой? - PullRequest
0 голосов
/ 27 ноября 2018

In componentOne.ts Я отправляю данные через sharedService as,

  this.sharedService.sendData(this.getCheckedProduct);

In componentTwo.ts Я подписываюсьданные, как,

      productList: any = [];

      getAllProducts: any = [];

      ngOnInit() {
        this.sharedService.getData().subscribe(data => {
          this.productList = data;
          this.getProduct();
        });
      }

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

  getProduct() {
    let tempArray = [];
    this.productList.forEach(element => {
        this.appService.getRest(AppConfig.settings.product.getProducts + '/' + element.product_obj_id).subscribe(res => {
          tempArray.push(res.data);
        });
    });
    this.getAllProducts = tempArray;
  }

Мне нужно передатьid element.product_obj_id, чтобы получить необходимые данные этого идентификатора ..

Я попытался , изменив вышеуказанное, вот так:

  ngOnInit() {
    this.sharedService.getData().subscribe(data => {
      data.forEach(element => {
        this.getProduct(element);
      })
    });
  }

  async  getProduct(element) {
    let asyncResult = await this.appService.getRest(AppConfig.settings.product.getProducts + '/' + element.product_obj_id).toPromise();
    this.getAllProducts.push(asyncResult['data']);
  }

Внутри async getProduct(element) функция iя получаю данные this.getAllProducts, но в html я не получаю данные.

HTML:

<div *ngFor="let product of getAllProducts">
 Getting data
</div>

Если я изменил вышеуказанное с async

<div *ngFor="let product of getAllProducts | async">
 Getting data
</div>

Я получаю сообщение об ошибке, как

ERROR Error: InvalidPipeArgument: '' for pipe 'AsyncPipe'
    at invalidPipeArgumentError

Чтобы объяснить подробно, мне нужно отправить данные через sharedservice в componentone и получить их в componenttwo затеммне нужно получить product_obj_id из этих общих сервисных данных.

При передаче каждого идентификатора я получу данные об этом конкретном продукте и мне нужноили окончательные данные, полученные от this.appService.getRest(AppConfig.settings.product.getProducts + '/' + element.product_obj_id).toPromise(); до getAllProducts ..

AppConfig.settings.product.getProducts 

- это URL.

Как достичь этого асинхронным способом.это я получаю данные

this.getAllProducts.push(asyncResult['data']);

но за пределами функции я не получаю значение, также getAllProducts больше не работает над любым сценарием в html ..

В Сценарий 1 , объясненный в верхней части этого вопроса, я дал следующее

this.getAllProducts = tempArray;

Этот параметр дает пустой массив в качестве значения, и поэтому я только пытаюсь использовать функцию async.

Проще говоря, мне нужно получить окончательные данные из this.getAllProducts, которые будут получены из service с методом get, для которого мне нужно передать идентификатор в URL.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

AsyncPipe применяется к Observable.В вашем случае вы применяете его на getAllProducts, что, на мой взгляд, Array.Следовательно, вы получаете эту ошибку.

Возможное решение:

  1. удалить async из вашего цикла for getAllProducts
  2. MakegetAllProducts вернуть Observable ваших продуктов

Примечание: поскольку вы просматриваете productList и вызываете webapi для получения продуктов, вам, возможно, придется использоватьmergeMap.

Образец решения 2:

Я считаю, что решение 2 лучше для вас, так как вы productList содержат все продукты , для которых вам нужно нажатьwebapi для получения подробной информации о продуктах .

Learn MergeMap здесь

Пример кода (не проверено, и вам необходимо добавить код для обработки ошибокс catchError):

import { from } from 'rxjs';
import { mergeMap, map, combineAll } from 'rxjs/operators';

this.getAllProducts = from(this.productList)
    .pipe( 
        mergeMap(element =>
            this.appService.getRest(AppConfig.settings.product.getProducts + '/' + element.product_obj_id).pipe(
                map(res => res['data'])
            )
        ),
        combineAll()
    )

<div *ngFor="let product of getAllProducts | async">
    Getting data
</div

Объяснение:

, так как вы productList - это Array, и вам нужно пройти через него и запустить запрос для каждого productобъект в этом Array

from(this.productList) превращает каждый объект в productList в наблюдаемую.Мы добавляем pipe и, используя mergeMap, мы можем запустить запрос для каждого из product, следовательно, вы видите this.appService.getRest(AppConfig.settings.product.getProducts + '/' + element.product_obj_id) это внутри mergeMap.Затем мы map response, которые мы получаем из webapi, и возвращаем данные только с использованием res['data'].Наконец, мы combineAll ответ, который возвращает Observable<[]>, который мы установили в getAllProducts, следовательно, getAllProducts является Observable, и мы можем использовать AsyncPipe для него.

Изменить:

Добавьте следующее в constructor вместо ngOnit

const getAllProducts = this.sharedService.getData().pipe(
  mergeMap(data=> from(data))
).pipe( 
    mergeMap(element =>
        this.appService.getRest(AppConfig.settings.product.getProducts + '/' + element.product_obj_id).pipe(
            map(res => res['data'])
        )
    ),
    combineAll()
)
0 голосов
/ 27 ноября 2018

Просто присвойте свои данные внутри асинхронного вызова следующим образом -

getProduct() {
    let tempArray = [];
    this.productList.forEach(element => {
        this.appService.getRest(AppConfig.settings.product.getProducts + '/' + element.product_obj_id).subscribe(res => {
          tempArray.push(res.data);
          this.getAllProducts = tempArray; // Here
        });
    });
  }

PS: в вашем случае использования нет необходимости использовать pipe async.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...