在我的服务类的构造函数中,我将http调用发送到服务器以检索存储在productCategories数组中的产品类别数据。然后在我的组件的ngInit()函数中,我调用服务来检索productCategories数组,但是我得到一个错误,即productCategories未定义。
似乎正在发生的事情是服务的构造函数将调用放置到服务器,然后在检索产品类别数据之前返回。当组件为此数据调用服务的getCategory(x,y)方法时,从服务的构造函数先前对服务器的调用仍未完成,因此它声明productCategories数组未定义。然后调用完成,productCategories数组将记录到控制台。
我该如何解决这个问题?
@Injectable()
export class ProductCategoryService {
private productCategories: ProductCategory[];
private categoriesUrl = "/api/product/categories";
constructor(private http: Http) {
console.log('ProductCategory.constructor() called');
this.getProductCategoriesDb();
}
private getProductCategoriesDb() {
console.log('ProductCategory.getCategories() called');
this.http.get(this.categoriesUrl)
.toPromise()
.then((response: Response) => {
this.productCategories = response.json();
console.log('this.productCategories = ' +
JSON.stringify(this.productCategories));
})
.catch(this.handleError);
}
public getProductCategory(name, type) {
return this.productCategories
.filter(category => (category.name == name && category.type == type))[0];
}
}
组件:
export class ProductCategoryComponent implements OnInit {
category: string;
type: string;
productCategory: ProductCategory = new ProductCategory();
constructor(private route: ActivatedRoute, private productCategoryService:
ProductCategoryService) { }
ngOnInit() {
this.route.params.subscribe(params => {
this.category = params["category"];
this.type = params["type"];
console.log("category = " + this.category)
console.log("type = " + this.type)
this.productCategory =
this.productCategoryService.getProductCategory(this.category, this.type);
console.log("productCategory = " + this.productCategory);
})
}
}
记录语句的顺序:
ProductCategory.constructor()调用---- product-category.service.ts:27
ProductCategory.getCategories()调用---- product-category.component.ts:23
错误:productCategories数组未定义:
ProductCategoryComponent_Host.html:1 ERROR TypeError:无法读取未定义的属性“过滤器” 在ProductCategoryService.webpackJsonp ... / .. / .. / .. / .. / src / app / product-category / product-category.service.ts.ProductCategoryService.getProductCategory(product-category.service.ts:39) 在SafeSubscriber._next(product-category.component.ts:27) 在SafeSubscriber.webpackJsonp ... / .. / .. / .. / rxjs / Subscriber.js.SafeSubscriber .__ tryOrSetError(
最后打印productCategories数组--- product-category.service.ts:33
this.productCategories = [{“_ id”:“599c5d93f36d286317108ffd”,“name”:“Furniture”,“type”:“Living Room”,“image”:[{“label”:“Living Room”,“命名 “:” LivingRoom1.jpg “},{” 标签 “:” 沙发”, “名”: “LivingRoom2.jpg”},{ “标签”: “睡眠者”, “名”: “LivingRoom3.jpg”}, { “标签”: “双人沙发”, “名”: “LivingRoom4.jpg”},{ “标签”: “椅子”, “名”: “LivingRoom5.jpg”},{ “标签”: “脚垫”,”命名 “:” LivingRoom6.jpg “},{” 标签 “:” Chaisers”, “名”: “LivingRoom7.jpg”},{ “标签”: “躺椅”, “名”: “LivingRoom8.jpg”}, {“label”:“Sectionals”,“name”:“LivingRoom9.jpg”},{“label”:“偶尔表”,“名称”:“LivingRoom10.jpg”}],“items”:[“沙发” ,“露宿者”,“情侣”,“椅子”,“奥斯曼”,“轻便小屋”,“躺椅”,“剖面”,“偶尔的桌子”]}]
答案 0 :(得分:0)
简短的回答是不要修复它,重写它。 抛出错误背后的推理是正确的,但是在处理来自服务器的数据时,您可能应该考虑不同的方法。
这是第一步,可以进一步改进。
@Injectable()
export class ProductCategoryService {
productCategoriesSbj: ReplaySubject<ProductCategory[]> = new ReplaySubject();
private categoriesUrl = "/api/product/categories";
constructor(private http: Http) {
}
getProductCategoriesDb(): Observable<ProductCategory[]> {
return this.http.get(this.categoriesUrl)
.subscribe(response => this.productCategoriesSbj.next(response.json()))
.catch(this.handleError);
}
getProductCategory(categories: ProductCategory[], name: string, type: string) {
return categories.filter(category =>
(category.name == name && category.type == type)
)[0];
}
}
然后在你的组件中:
export class ProductCategoryComponent implements OnInit, OnDestroy {
category: string;
type: string;
productCategory: ProductCategory = new ProductCategory();
productCategorySub: Subscription = new Subscription();
constructor(private route: ActivatedRoute,
private productCategoryService: ProductCategoryService){
}
ngOnInit() {
this.route.params.subscribe(params => {
this.category = params["category"] || '';
this.type = params["type"] || '';
this.productCategoryService.getProductCategoriesDb();
productCategorySub = this.productCategoryService
.productCategoriesSbj
.subscribe(categories => {
// now categories contain parsed response from the server
this.productCategory = this.productCategoryService
.getProductCategory(categories, this.category, this.type);
});
})
}
}
ngOnDestroy() {
// unsubscribe from observable to avoid memory leaks
this.productCategorySub.unsubscribe();
}
解释不多,但我希望它有所帮助。