This is, as far as I can tell, a logic problem that I just can't wrap my head around. Using next-connect
I have a function for updating an entry in the database:
.put(async (req, res) => {
const data = req.body;
const { dob, roles, cases } = data ?? {};
const convertedDob = dob ? new Date(dob) : null;
const roleIds = roles?.map((role: Role) => {
return { id: role.id };
});
const caseIds = cases?.map((_case: Case) => {
return { id: _case.id };
});
data.dob = convertedDob;
delete data.roles;
delete data.formData;
const user = await getUserDataFromSession(req, res);
throwIfNoCurrentTeam(user?.currentTeam);
try {
const person: Person = await prisma.person.update({
where: { id: data.id },
data: {
...data,
roles: { connect: roleIds },
cases: { connect: caseIds },
},
});
if (person && person.linkedIds) {
// get linkedId arrays of all people linked to this person
const associatedPeopleIdArrays = await prisma.$transaction(
person.linkedIds.map((id) =>
prisma.person.findUnique({
where: { id },
select: { id: true, linkedIds: true },
}),
),
);
const backLinkArray = associatedPeopleIdArrays.map((linkedPerson) => {
const linkedPersonIds = linkedPerson?.linkedIds;
const linkedPersonOwnId = linkedPerson?.id;
// if the array of linkedIds already includes the person we are back-linking, enter next check
if (linkedPersonIds?.includes(person.id)) {
// if they both include each other, do nothing
if (person.linkedIds.includes(linkedPersonOwnId as string)) {
return { id: linkedPersonOwnId, linkedIds: linkedPersonIds };
}
// if linkedPersonIds includes person.id but person.linkedIds does not include linkedPersonOwnId, remove the relationship
return { id: linkedPersonOwnId, linkedIds: linkedPersonIds.filter((id) => id !== person.id) };
// else add the current person's id to each person's array that we are back-linking
} else {
return {
id: linkedPersonOwnId,
linkedIds: linkedPersonIds ? [...linkedPersonIds, person.id] : [person.id],
};
}
});
// write the new linkedId array to each associated person
await prisma.$transaction(
backLinkArray.map((linkedPerson) =>
prisma.person.update({
where: { id: linkedPerson?.id },
data: {
linkedIds: linkedPerson?.linkedIds,
},
}),
),
);
}
return res.status(200).json({ updated: person });
} catch (err: any) {
console.log({ err });
handleApiError('Failed to update person', 500, err);
}
});
I've left comments to try and follow what's happening which I have left in in case they help to understand what I'm trying to do. I've created logs all over the place to see what's happening, but the issue really is in the if/else logic.
The function works correctly to establish a relationship between two people. If an id
is added to a person's linkedIds
array, then that person's id
is also added to the array of the associated person.
But I need additional logic to remove a relationship if an id
is removed from a person's linkedIds
, and this is where it's breaking down. Currently the logic seems to correctly enter this if statement: if (linkedPersonIds?.includes(person.id))
, but then it always enters the following if statement: if (person.linkedIds.includes(linkedPersonOwnId as string))
.
I would expect that if a person was removed from the linkedIds
array then this statement would return false, but it doesn't. It returns true every time, so the relationship never gets deleted. What is going wrong? What have I missed?
Sorry it's such a mess, I hope you're able to follow this madness!