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
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] };
});
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)
}
}, []);
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);