I have here a map
function for an array of object
and also added some condition
userList.map((item) => {
const newFilter = dailyData.filter((value) => {
return value.author == item.MSM;
});
let obj_idx = userList.findIndex(
(obj) => obj.MSM == newFilter[0]?.author
);
const newArr = userList?.map((obj, idx) => {
if (idx == obj_idx) {
return {
...obj,
storeTimeIn: newFilter[0]?.store,
timeIn: newFilter[0]?.date_posted,
storeTimeOut: newFilter[newFilter.length - 1]?.store,
timeOut: newFilter[newFilter.length - 1]?.date_posted,
};
} else {
return obj;
}
});
console.log(newArr);
setAttendanceData(newArr);
});
that just check if the Item exist in the array before updating it.
and this condition here works fine
if (idx == obj_idx) {
return {
...obj,
storeTimeIn: newFilter[0]?.store,
timeIn: newFilter[0]?.date_posted,
storeTimeOut: newFilter[newFilter.length - 1]?.store,
timeOut: newFilter[newFilter.length - 1]?.date_posted,
};
}
as seen in this picture
but when my condition becomes false the whole array of object becomes empty again
my hunch is I'm setting the state wrongly . which appear in the setAttendanceData(newArr)
this state is just an empty array state const [attendanceData, setAttendanceData] = useState([]);
. is there a way to not update the whole array of object when the condition gets false like how can I use spread operator in this situation. TIA
CodePudding user response:
I feel you need to add a little more description including the current react component and little bit about your inputs/outputs for a more refined answer.
userList.map((item, index, self) => {
const newFilter = dailyData.find((value) => {
return value.author === item.MSM;
});
// this is only needed if there can be multiple
// occurrence of same obj.MSM in 'userList' array
let obj_idx = self.findIndex((obj) => obj.MSM === newFilter[0] ? .author);
// why are you doing this
const newArr = self ? .map((obj, idx) => {
if (idx == obj_idx) {
return {
...obj,
storeTimeIn: newFilter[0] ? .store,
timeIn: newFilter[0] ? .date_posted,
storeTimeOut: newFilter[newFilter.length - 1] ? .store,
timeOut: newFilter[newFilter.length - 1] ? .date_posted,
};
} else {
return obj;
}
});
console.log(newArr);
// why are you doing this , updating state on every iteration
// after user.map attendanceData will only reflect for the last index in userList
setAttendanceData(newArr);
});
But if my assumptions are correct, this following code snippet may help you in some way.
setAttendanceData(
// make sure to run setAttendanceData only once
userList.map((item, index, self) => {
const newFilter = dailyData.find((value) => {
return value.author === item.MSM;
});
const obj_idx = self.findIndex((obj) => obj.MSM === newFilter[0] ? .author);
// there can be refinement around this but i feel this is what you need
if (index === obj_idx) {
return {
...obj,
storeTimeIn: newFilter[0] ? .store,
timeIn: newFilter[0] ? .date_posted,
storeTimeOut: newFilter[newFilter.length - 1] ? .store,
timeOut: newFilter[newFilter.length - 1] ? .date_posted,
};
} else {
return obj;
}
})
);
CodePudding user response:
First, I would re-examine this logic. You're calling map
inside of map
on the same array, which is confusing. The top level map is used more like a forEach
than a map because nothing is done with the output. You're also updating state on each iteration of the loop. I'm not sure how React handles this situation.
Try to only set state once the data is in the shape you want. Ideally it would only require one pass through the array. Here is an example:
const [attendanceData, setAttendanceData] = useState([]);
const [userList, setUserList] = useState([
{ MSM: "Edmond" },
{ MSM: "Dantes" },
{ MSM: "Conan" },
]);
const [dailyData, setDailyData] = useState([
{ author: "No one", store: "store", date_posted: "a date" },
{ author: "Edmond", store: "store", date_posted: "a date" },
{ author: "Conan", store: "store", date_posted: "a date" },
]);
useEffect(() => {
const mappedUserList = userList.map((user) => {
// Find the daily data author that matches the current user.
const day = dailyData.find((value) => {
return value.author == user.MSM;
});
if (!day) {
// If no author matched in daily data, return the user unchanged.
return user;
} else {
return {
...user,
storeTimeIn: day.store,
timeIn: day.date_posted,
// I'll leave these lines for you to figure out
// since I don't understand why you're getting the last element of the filtered data.
// storeTimeOut: filteredDailyData[filteredDailyData.length - 1]?.store,
// timeOut: filteredDailyData[filteredDailyData.length - 1]?.date_posted,
};
}
});
setAttendanceData(mappedUserList);
}, [userList, dailyData]);
console.log(attendanceData);