Угловая наблюдаемая обработка нескольких абонентов - PullRequest
0 голосов
/ 27 марта 2019

В моем компоненте ngOnInit ComProductService сначала получает категории продуктов, обрабатывает третий уровень категорий и сохраняет их в proCatThird в сервисе. Затем в моем методе fillFormValues ​​() мне нужно получить значение proCatThird из ComProductService. Однако значение, возвращаемое из proCatThird, не определено. Есть ли какие-то правильные способы передачи значения от одного подписчика другому?

ComProductService.service.ts

export class ComProductService {
 baseUrl = environment.apiUrl + 'comProducts/';
 proCatThird: ProCatThird[];
constructor(private http: HttpClient,
 private authService: AuthService,
 private errorHandler: ErrorService) { }

 getProductCategories(): Observable<ProCatFirst[]> {
  return this.http
   .get(this.baseUrl)
   .pipe(
    map((response: ProCatFirst[]) => {
     if (response) {
      this.proCatThird = [];
      response.forEach((first) => {
        first.proCatSeconds.forEach((second) => {
          second.proCatThirds.forEach((third) => {
            this.proCatThird.push(third);
          });
        });
      });
      return response;
    }
  })
);
}

component.ts

constructor(
private activatedRoute: ActivatedRoute,
private comProductService: ComProductService,
) { }

ngOnInit() {
this.comProductService.getProductCategories().subscribe((response) => {
  this.proCatFirst = response;
});

this.fillFormValues();

}

fillFormValues() {

  this.activatedRoute.data.subscribe(data => {
    this.product = data['product'];
    this.productForm.patchValue({
        name: this.product.name,
        category: this.product.category,
    });

    const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
  });
}

1 Ответ

1 голос
/ 27 марта 2019

Проблема с кодом сейчас заключается в том, что fillForm запускается без ожидания ответа сервера, а свойство proCatThird не заполняется требуемым ответом.

Пожалуйста, сделайте это в вашем компоненте:

constructor(
private activatedRoute: ActivatedRoute,
private comProductService: ComProductService,
) { }

ngOnInit() {
  this.comProductService.getProductCategories().subscribe((response) => {
    this.proCatFirst = response;
    this.fillFormValues(); // fill form values when the data has been received from server
  });
}

fillFormValues() {
  this.activatedRoute.data.subscribe(data => {
    this.product = data['product'];
    this.productForm.patchValue({
        name: this.product.name,
        category: this.product.category,
    });

    const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
  });
}

РЕДАКТИРОВАТЬ: ПРЕДЛОЖЕНИЕ для подписки в рамках подписки

    ngOnInit() {
      this.comProductService.getProductCategories()
        .pipe(
          mergeMap((response) => {
            this.proCatFirst = response;
been received from server
            return this.activatedRoute.data;
          })
        )
        .subscribe(data => {
          this.product = data['product'];
          this.productForm.patchValue({
              name: this.product.name,
              category: this.product.category,
          });

          const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
        });

    }

Таким образом, у вас будет только одна подписка, которая срабатывает при загрузке страницы (компонент init);

...