Jao Ming
Jao Ming

Reputation: 19

HttpClient how to convert nested json and map to model in Angular 7

I have nested JSON object and I want to store in the Array private categoryModule: CategoryModel[] = []; with Angular 7 HttpClient.

JSON object:

[
  {
    id: 1, name: 'Mr. Nice', descriptio: 'dasdad', image: "sada", product: [
      { id: 0, name: 'Milos', descriptio: "sdada", number: 1, image: 'ssad' },
    ]
  },
  {
    id: 2, name: 'Misko', descriptio: 'dasdad', image: "sada", product: [
      { id: 0, name: 'Milos', descriptio: "sdada", number: 1, image: 'ssad' },
      { id: 1, name: 'Somi', descriptio: "haha", number: 1, image: 'haha' }
    ]
  }
]

My model ProductModel is :

export class ProductModel  {

  constructor(
    public id:number,
    public name: string, 
    public description: string, 
    public numberOfProduct: number, 
    public image: string) {}
}

My model CategoryModel:

export class CategoryModel  {

  public id: number;
  public name: string;
  public description: string;
  public image: string;
  public products: ProductModel[] ;


  constructor(
      name: string, 
      desciption: string, 
      image: string = null, 
      products: ProductModel[], 
      id: number) {
    this.id = id;
    this.name = name;
    this.description = desciption;
    this.image = image;
    this.products = products;
  }
}

This is my service for get method :

  /** GET heroes from the server */
  getCategory(): Observable<CategoryModel[]> {
    return this.http.get<CategoryModel[]>(this.cateogryUrl).pipe(
    /* map(products => {
        return Object.values(products)

      }),*/
      catchError(this.handleError('getProduct', []))
    )
  }

This is my code component for storing data in Array.

 getCagegoryFromServer() {
    this.dataStorageServiceServiceta.getCategory().subscribe((category :CategoryModel[]) => {

      this.categoryModule = category;
      console.log(this.categoryModule[0].products[0] + "milos car");
    })
  }

I have problem in my categoryModule Array because products is undefined. Obviously products not initialized. Do any know how to fix that?

Upvotes: 0

Views: 6659

Answers (1)

John
John

Reputation: 10069

If you want to map your json response to model classes, then you need to map the json response to the model classes:

getCategory(): Observable<CategoryModel[]> {
  return this.http.get<CategoryModel[]>(this.cateogryUrl).pipe(
    map(categories => categories.map(categoryJson => new CategoryModel(
      categoryJson.name, 
      categoryJson.descriptio, 
      categoryJson.image, 
      categoryJson.product.map(productJson => new ProductModel(
        productJson.id,
        productJson.name, 
        productJson.descriptio, 
        productJson.number, 
        productJson.image
      )),
      categoryJson.id
    ))),
    catchError(this.handleError('getProduct', []))
  )
}

This being said, it's unclear why you are mapping to javascript classes, as your classes don't seem to have any methods associated with them. As pointed out by a few comments, you could just make use of the returned json directly, and use typescript interfaces to provide IntelliSense / error checking.

If you are going to stick with javascript classes, using a single options argument in the class constructor, rather than individual property arguments, would make things easier.

For example

export class CategoryModel  {

  public id: number;
  public name: string;
  public description: string;
  public image: string;
  public products: ProductModel[] ;


  constructor(args: {
    name: string, 
    desciptio: string, 
    image: string = null, 
    product: {
      id: number,
      name: string, 
      descriptio: string, 
      number: number, 
      image: string
    }[], 
    id: number
  }) {
    this.id = args.id;
    this.name = args.name;
    this.description = args.desciptio;
    this.image = args.image;
    this.products = args.product.map(json => new ProductModel(json));
  }
}

This would simplify the getCategory() method to:

getCategory(): Observable<CategoryModel[]> {
  return this.http.get<CategoryModel[]>(this.cateogryUrl).pipe(
    map(categories => categories.map(categoryJson => new CategoryModel(categoryJson))),
    catchError(this.handleError('getProduct', []))
  )
}

Upvotes: 4

Related Questions