0

I have a two json objects. i need to merge those in a single object which has same id.

Example

 const [orderdetails, setOrderdetails] = useState([]);
  const [ordertracking, setOrdertracking] = useState([]);
  
  useEffect(() => {
    fetch('first api')
      .then((response) => response.json())
      .then((json) => setOrderdetails(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, []);

  useEffect(() => {
    fetch('second api')
      .then((response) => response.json())
      .then((json) => setOrdertracking(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, []);

Sample data

First api response in orderdetails

{
    "statusCode": "200",
    "message": "success",
    "content": [
         { subject_id: 711, topics: ["Test", "Test2"] },
         { subject_id: 712, topics: ["topic1", "Topic2"] }
]
}

Second api response in ordertracking

{
        "statusCode": "200",
        "message": "success",
        "content": [
              {subject_id: 711, subject_name: "Science"},
               {subject_id: 712, subject_name: "Maths"}
    ]
    }

I want the merged result to be:

const result = [
  {
    subject_id: "711",
    subjectName: "Science",
    topics: [ "Test", "Test2" ]
  },
  {
    subject_id: "712",
    subjectName: "Maths",
    topics: [ "topic1", "Topic2" ]
  }
];

As you can see there are two api response in a josn format I need to merge those json object which is inside a content which has same 'subject_id' and rest of the values as a single data.

I need a solution in javascript for my react native app if you can suggest me a react native code

A. Chithrai
  • 121
  • 11
  • There's no [JSON](https://www.json.org/json-en.html) in your question. Also there's no such thing as a _"json array"_. The shown data structures are simple objects with some properties and one of them being an array. – Andreas Feb 13 '22 at 17:22

3 Answers3

0

I guess you are looking for this answer

let arr1 = [
         { subject_id: 711, topics: ["Test", "Test2"] },
         { subject_id: 712, topics: ["topic1", "Topic2"] }
];

let arr2 = [
         {subject_id: 711, subject_name: "Science"},
         {subject_id: 712, subject_name: "Maths"}
];

let res = arr1.map((item, i) => Object.assign({}, item, arr2[i]));

// Or the same with es6 syntax
let resEs6 = arr1.map((item, i) => {
    return { ...item, ...arr2[i] };
  });

Laurenz Honauer
  • 254
  • 1
  • 12
0

I would suggest instead of making a result an array like this:

 const result = [
  {
    subject_id: "711",
    subjectName: "Science",
    topics: [ "Test", "Test2" ]
  },
  {
    subject_id: "712",
    subjectName: "Maths",
    topics: [ "topic1", "Topic2" ]
  }
];

You make it an object mapped with the subject_id:

 const result = {
  "711":{
    subjectName: "Science",
    topics: [ "Test", "Test2" ]
  },
  "712":{
    subjectName: "Maths",
    topics: [ "topic1", "Topic2" ]
  }
];

And your useEffect would be cleaner if you use async/await like this:

 const [orderdetails, setOrderdetails] = useState([]);
  const [ordertracking, setOrdertracking] = useState([]);
  
  useEffect(async () => {
   try{
    var res1 = await fetch('first api')
    var data1 = await res1.json()
    var res2 = await fetch('second api')
    var data2 = await res2.json()
    setOrderdetails(data1)
    setOrdertracking(data2)
    var res = {}
    for(let d1 of data1.content){
      res[d1.subject_id] = {
         topics:d1.topics
      }
      
    }
    for(let d2 of data2.content){
      if(res[d2.subject_id]){
         res[d2.subject_id].subjectName = d2.subjectName
      }
     
      
    }
    console.log(res)
   }catch(e){
     console.error(e)
   }finally{
    setLoading(false)
   }
  }, []);

If you want to keep result an array use this

 const [orderdetails, setOrderdetails] = useState([]);
  const [ordertracking, setOrdertracking] = useState([]);
  
  useEffect(async () => {
   try{
    var res1 = await fetch('first api')
    var data1 = await res1.json()
    var res2 = await fetch('second api')
    var data2 = await res2.json()
    setOrderdetails(data1)
    setOrdertracking(data2)
    var res = []
    for(let d1 of data1.content){
      res.push({...d1,...data2.content.find(d2=>d2.subject_id==d1.subject_id)})
      
    }
    console.log(res)
   }catch(e){
     console.error(e)
   }finally{
    setLoading(false)
   }
  }, []);
A. Chithrai
  • 121
  • 11
JaivBhup
  • 792
  • 4
  • 7
0

You can just use ForEach loop and Find method to do that...

const res1 = {
  statusCode: '200',
  message: 'success',
  content: [
    { subject_id: 711, topics: ['Test', 'Test2'] },
    { subject_id: 712, topics: ['topic1', 'Topic2'] },
  ],
};

const res2 = {
  statusCode: '200',
  message: 'success',
  content: [
    { subject_id: 711, subject_name: 'Science' },
    { subject_id: 712, subject_name: 'Maths' },
  ],
};

let result = [
  // {
  //   subject_id: "711",
  //   subjectName: "Science",
  //   topics: [ "Test", "Test2" ]
  // },
  // {
  //   subject_id: "712",
  //   subjectName: "Maths",
  //   topics: [ "topic1", "Topic2" ]
  // }
];

res1.content.forEach((item) => {
  result.push({
    subject_id: item.subject_id,
    topics: item.topics,
    subject_name: res2.content.find(
      (elem) => elem.subject_id == item.subject_id
    ).subject_name,
  });
});

console.log(result);
JeX
  • 95
  • 1
  • 10