1

I am trying to build a tree structure by traversing a given ID and attaching its child to the tree. It always assigns user.children = 'sample' instead of fetched user children from user.children = usrChild, also tried usrArr[index].children = 'sample'

What I am trying to implement: using a userID, I will fetch its children, now for each children i will fetch their children until there are no children left.

function UserProfile.getUserChildren returns a promise with data consisting of all the children. Now, we iterate each children and fetch their children

Output Expected Visually:

enter image description here

Programatically What I am expecting:

[
    {   
        text: {
            userID: 1
            name: 'Mike'
        },
        children:[
            {
                text: {
                    userID: 2
                    name: 'John'
                },
                children [
                    {
                        text: {
                            userID: 4
                            name: 'Hero'
                        },
                        children []
                    }
                ]
            },
            {
                text: {
                    userID: 3
                    name: 'Kelvin'
                },
                children []
            }

        ]
    }
]

Code in Node JS:

let UserProfile = require('./UserProfile');

// Love Dad 83273010
let userID = 51405009;
var allDistributors = Array();
  rootUser = new Object();
  rootUser.text = {userID:userID,name:'Root'};
  rootUser.children = [];
function getUserTree(userID){
  return new Promise( (resolve,reject) => {
    /*
    * UserDownline Return User child Array
    * Format: 
    * [
    *   {   text: {
    *           userID: 45
    *           name: 'Mike'
    *       },
    *       children:[]     
    *   }
    * ]
    * 
    */
     UserProfile.getUserChildren(userID).then(async (data) => {
      if(data.length > 0){
        rootUser.children = data;
        /*
        * Iterating each user to fetch and assign its child
        */
        await rootUser.children.forEach(async (user,index,usrArr) => {

          user.children = 'sample'

          await getUserTree(user.text.title).then( async(usrChild) => {
              /*
                Assigning child to root user
              */
              usrArr[index].children = usrChild; // STILL NOT ABLE TO ASSIGN VALUE and return user.children as 'sample'
          }).then(resolve(rootUser));



        });
        //resolve(rootUser)
        //console.log(rootUser)
        //return Promise.all(rootUser);
      }else
      resolve([]); // return empty child when no child exist
    });
    //return rootUser.children;

    //console.log(rootUser);
  });


}
//console.log(JSON.stringify(rootUser));
getUserTree(userID).then((data) => {
  console.log(JSON.stringify(data));
});
Ashish
  • 1,309
  • 1
  • 11
  • 17
  • `await xxx.forEach(async` - this does not do what you think it does ... since `forEach` returns (immediately) `undefined`, nothing inside the forEach callback is `await`ed on – Jaromanda X Mar 09 '19 at 07:53
  • Any idea how can I achieve it or any other way to iterate, so assignment is performed upon completion of getUserTree ? – Ashish Mar 09 '19 at 10:31
  • Array.map with promise.all – Jaromanda X Mar 09 '19 at 10:46

1 Answers1

0

As Jaromanda X pointed out, rootUser.children.foreach returns undefined instead of a promise. Consider using rootUser.children.map instead. That returns an array of Promises that you can await on using Promise.all, which returns a promise of an array. Since map does not modify the original array, you would need to assign rootUser.children to the awaited result of Promise.all

jro
  • 900
  • 1
  • 10
  • 21
  • Still same issue, as foreach – Ashish Mar 09 '19 at 12:56
  • Your example expected result doesn't show a `user.text.title` property. This results in the id passed to the getUserTree function to be undefined. You would also need to return the result of getUserTree in the map – jro Mar 09 '19 at 13:14