0

I have a json file which contains the list of products.

[{"id":76,
  "name":"A",
  "description":"abc",
  "price":199,
  "imageUrl":"image.jpg",
  "productCategory":[{
    "categoryId":5,
    "category":null
   },{
    "categoryId":6,
    "category":null
   }
]}

I then have a second json file with a list of categories which look like so:

[{"id":5,"name":"red"},
{"id":6,"name”:"blue"}]

What is the best way to join the categories of this two json files in Angular? This is what I aim to achieve:

[{"id":76,
  "name":"A",
  "description":"abc",
  "price":199,
  "imageUrl":"image.jpg",
  "productCategory":[{
    "categoryId":5,
    "category":red
   },{
    "categoryId":6,
    "category":blue
   }
]}
8
  • 1
    what is your expected result? Commented May 2, 2019 at 11:40
  • like so: "productCategory":[{ "categoryId":5, "category": red } Commented May 2, 2019 at 11:48
  • why having two category with same id and different name red and blue? Commented May 2, 2019 at 11:49
  • Sorry, my bad. they are 2 different categories. Im gonna fix it. But one product can have 2 categories Commented May 2, 2019 at 11:52
  • this product belong 2 category, why you want return only 5 red ? Commented May 2, 2019 at 12:01

2 Answers 2

0

I make a stackblitz that use a service to retreive the data. Yes, the way is using switchMap and map. SwitchMap receive an array and must return an observable. with map, we transform the data received and return the data transformed

this.dataService.getCategories().pipe(
         //first get the categories, the categories is in the
         //variable cats
         switchMap((cats:any[])=>{
           return this.dataService.getProducts().pipe(map((res:any[])=>{
               res.forEach(p=>{ //with each product
                 p.productCategory.forEach(c=>{ //with each productCategory in product
                   //equals a propertie "category" to the propertie "name" of the cats
                   c.category=cats.find(x=>x.id==c.categoryId).name 
                 })
               })
               return res
           }))
     })).subscribe(res=>{
       console.log(res)
     })

If only has an unique product we can make

this.dataService.getCategories().pipe(
         switchMap((cats:any[])=>{
           return this.dataService.getUniqProduct(2).pipe(map((res:any)=>{
                 res.productCategory.forEach(c=>{
                   c.category=cats.find(x=>x.id==c.categoryId).name
                 })
               return res
           }))
     })).subscribe(res=>{
       console.log(res)
     })

We can improve our dataService "cached" the categories

  getCategories() {
    if (this.categories)
      return of(this.categories);

    return http.get(......).pipe(tap(res=>{
       this.categories=res;
    }))
  }

NOTE:In the stackbit I simulate the call to an http.get(...) using "of"

Sign up to request clarification or add additional context in comments.

Comments

0

You can use filter function for your requirement as below

let products = [{
      "id": 76,
      "name": "A",
      "description": "abc",
      "price": 199,
      "imageUrl": "image.jpg",
      "productCategory": [{
        "categoryId": 2,
        "category": null
      }, {
        "categoryId": 1,
        "category": null
      }]
    }, {
      "id": 77,
      "name": "B",
      "description": "abcd",
      "price": 1997,
      "imageUrl": "image.jpg",
      "productCategory": [{
        "categoryId": 5,
        "category": null
      }, {
        "categoryId": 6,
        "category": null
      }]
    },
    {
      "id": 78,
      "name": "C",
      "description": "abcde",
      "price": 1993,
      "imageUrl": "image.jpg",
      "productCategory": [{
        "categoryId": 4,
        "category": null
      }, {
        "categoryId": 6,
        "category": null
      }]
    }];


    let category = [{ "id": 5, "name": "red" }, { "id": 6, "name": "blue" }]

    let result = products.filter(p => {
      var exist = p.productCategory.filter(pc => category.find(c => c.id == pc.categoryId))[0];

      return exist;
    });

    console.log(result);

let products = [{
      "id": 76,
      "name": "A",
      "description": "abc",
      "price": 199,
      "imageUrl": "image.jpg",
      "productCategory": [{
        "categoryId": 2,
        "category": null
      }, {
        "categoryId": 1,
        "category": null
      }]
    }, {
      "id": 77,
      "name": "B",
      "description": "abcd",
      "price": 1997,
      "imageUrl": "image.jpg",
      "productCategory": [{
        "categoryId": 5,
        "category": null
      }, {
        "categoryId": 6,
        "category": null
      }]
    },
    {
      "id": 78,
      "name": "C",
      "description": "abcde",
      "price": 1993,
      "imageUrl": "image.jpg",
      "productCategory": [{
        "categoryId": 4,
        "category": null
      }, {
        "categoryId": 6,
        "category": null
      }]
    }];


    let category = [{ "id": 5, "name": "red" }, { "id": 6, "name": "blue" }]

    let result = products.filter(p => {
      var exist = p.productCategory.filter(pc => category.find(c => c.id == pc.categoryId))[0];

      return exist;
    });

    console.log(result);

3 Comments

Seems to be closer to the solution but I cant understand the let category = [{ "id": 5, "name": "red" }, { "id": 6, "name": "blue" }]. I am using an JSON file to store the categories data. I can't write it like that because it is hardcoded. At the moment I only get an empty array
I need to connect the name too. Not only the id
where is the name in your products?

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.