Observable的异步行为导致变量未定义

问题描述 投票:1回答:3

我在Angular2中创建了一个服务,它负责对Java服务进行REST调用,并使用HTTP Observable获取产品数组。

getAll(): Observable<Product[]>{
    let data$ = this.http
        .get(`${this.baseUrl}/productdata`, {headers: this.getHeaders()})
        .map(mapData)
        .catch(handleError);
    console.log(' object array:' , data$)
    return data$;
}

然后我在我的组件中为这个Observable编写了一个订阅者并放在了ngOnInit()方法中,并希望只提取放置在ngOnInit()中的第一个产品。

this.product = this.products [0];

ngOnInit() {
 this.productService
        .getAll()
        .subscribe(
            /* happy path */ p => this.products = p,
            /* error path */ e => this.errorMessage = e,
            /* onComplete */ () => this.isLoading = false);
this.product = this.products[0];
}

但OnInit方法的最后一个操作是由于Observable的异步行为导致产品未定义。同样,我无法使用product的属性在HTML组件中进行插值。我希望提取是自动的。那么你能为我提供一种方法吗?

angular asynchronous observable angular2-services angular2-components
3个回答
1
投票

你实际上回答了你自己的问题 - 因为它是异步的,你立即调用你对this.product = ...的调用,而observable需要一些时间才能返回。解决方案很简单:

ngOnInit() {
 this.productService
    .getAll()
    .subscribe(
        /* happy path */ p => {
            this.products = p;
            this.product = this.products[0];
        },
        /* error path */ e => this.errorMessage = e,
        /* onComplete */ () => this.isLoading = false);
}

在可观察回调中包含该集合。


0
投票

你的代码:

this.product = this.products[0];

在定义之前正在执行。将其移至您的成功功能

this.productService
    .getAll()
    .subscribe(
        /* happy path */ p => {
            this.products = p;
            this.product = this.products[0];
        },
        /* error path */ e => this.errorMessage = e,
        /* onComplete */ () => this.isLoading = false
);

0
投票

由于您正在使用observable,您可以利用可观察的所有方法,例如您已经使用的.map()函数。

this.productService
  .getAll()
  .map(products => products[0])
  .subscribe(
    /* happy path */ product => this.product = product,
    /* error path */ e => this.errorMessage = e,
    /* onComplete */ () => this.isLoading = false
  );
© www.soinside.com 2019 - 2024. All rights reserved.