0

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?

6
  • 2
    products is not initialized because it's named product in the JSON. Similarly, your description is named descriptio. Fix the JSON. Also, change your classes to interfaces: HttpClient will not create an instance of your classes. If you really need actual instances of your classes, then you need to map the json explictly, and create new instances explicitly. Commented Nov 26, 2018 at 12:49
  • Voting to close for typo. Commented Nov 26, 2018 at 12:50
  • OK, you can give me some examples, to I see how to fix that? Commented Nov 26, 2018 at 12:56
  • Well, just fix the JSON data: instead of product, use products. Instead of descriptio, use description. What is unclear? Commented Nov 26, 2018 at 13:00
  • You could use interfaces only (if classes are not required) so it will be "mapped" by itself. Commented Nov 26, 2018 at 13:11

1 Answer 1

4

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', []))
  )
}
Sign up to request clarification or add additional context in comments.

1 Comment

In categories.map() I have an error: Property 'map' does not exist on type 'CategoryModel'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.