Angular 2:由于接收服务器数据缓慢而导致接收错误

时间:2017-08-22 19:32:24

标签: angular typescript

在我的服务类的构造函数中,我将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”:[“沙发” ,“露宿者”,“情侣”,“椅子”,“奥斯曼”,“轻便小屋”,“躺椅”,“剖面”,“偶尔的桌子”]}]

1 个答案:

答案 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();
 }

解释不多,但我希望它有所帮助。