0

There are family members from a family tree stored in a database. The function (below) is supposed to query all the relatives from an user and add their contact and metadata in a list to be returned with everyone as an unique entry (order does not matter).

The problem is that this function only returns one degree of family. Everyone in lower branches of parentage are omitted.

async function getFamilyMembers(memberId) {
  let relativesList = [];
  let relativesdescendantsList = [];

  //local database
  //returns [] if nothing is found
  //returns an array of  objects if finds anything
  //items returned contain .id
  let relatives = await realmInstance
    .objects("FamilyMember")
    .filtered(`member.id="${memberId}"`);

  if (relatives) {
    relatives.forEach(async (relative) => {

      //external function to add relative metadata
      //like name, family branch, etc
      //it keeps the relative.id for use below
      let relativeData = fillData(relative);

      relativesList.push(JSON.stringify(relativeData));

      let newList = await getFamilyMembers(relative.id);
      relativesdescendantsList = [...newList, ...relativesList];
    });

    return relativesList.concat(relativesdescendantsList);
  } else {
    return relatives;
  }
}

I believe the problem is related to how the recursion is working. On the lowest branch, of course the kids do not have kids, so they return an empty array on

//relative.id is the id of the kid
let newList = await getFamilyMembers(relative.id);

So, the newList is an empty array, but the relativeData should not be empty, but on the console I get it as an empty array too, even though I (believe) I am pushing the kids metadate into the array.

Igor Marcos
  • 13
  • 1
  • 3
  • Why is `await getFamilyMembers` used? there is no API call in this method. It looks like you should not use recursion here as you are using API call. Instead just make API call when user clicks at the item of your tree. – StepUp Dec 04 '19 at 19:03
  • @StepUp the `await realmInstance` behaves like an API call, because it takes time to query the local disk. – Igor Marcos Dec 04 '19 at 19:20

1 Answers1

0

You are overwriting relativesdescendantsList = [...newList, ...relativesList]; in every forEach loop and then concatenate it relativesList.concat(relativesdescendantsList); outside the forEach loop but you only concat the last value of relativesdescendantsList that doesn't seem right to me.

Also you do if(relatives) ... else return relatives; So you return relatives only when there are none, why?

I have simplified it a bit:

async function getFamilyMembers(memberId) {
  let relativesList = [];

  let relatives = await realmInstance
    .objects("FamilyMember")
    .filtered(`member.id="${memberId}"`);

  relatives.forEach(async (relative) => {

    relativesList.push(fillData(relative));

    let newList = await getFamilyMembers(relative.id);
    relativesList = [...relativesList, ...newList];
  });

  return relativesList;
}
Molda
  • 5,619
  • 2
  • 23
  • 39