0

I've been working on a project and I'm currently working on a function which dynamically creates a dictionary data structure. The key used is the roll number of the student, and the value is the student's name.

But I'm unable to iterate through this dictionary. I've tried displaying the dictionary on console, but all I could see is an empty dictionary. I could see the elements in it, only if I expand it further. And when I display length using Obj.length on console, it displays 'undefined'.
I've read on other questions that Obj.length only works on arrays(i.e., enumerable types), and I've tried using an array instead of a dictionary. In that case, it shows an empty array and would not show values unless I manually expand it. I've also tried Obj.keys() method on the dictionary, and I've encountered the same issue.
This is the function's code:

function dictGenerator(rollnos, selectedValue) {
            var dict = {};
            for(let i = 0; i < rollnos.length; i++) {
                get(child(dbref, "RegisterNos/" + rollnos[i])).then((snapshot)=>{
                    if(Object.keys(snapshot.val()).length-1 == selectedValue){
                        dict[rollnos[i]] = snapshot.val()["name"];
                    }
                });
            }
            console.log(dict);
            console.log(dict.length);
        }
}

Any help on how I could iterate through my dictionary would be appreciated, Thank you.

Edit: code implementation using promises.

function dictGenerator(regnos, selectedValue) {
            const get_dict = async () => {
                var dict = {};
                for(let i = 0; i < regnos.length; i++){
                get(child(dbref, "RegisterNos/" + regnos[i])).then((snapshot)=>{
                    if(Object.keys(snapshot.val()).length-1 == selectedValue){
                        dict[regnos[i]] = snapshot.val()["name"];
                    }
                });
            }
            return dict;
            };

            get_dict().then((dict) => {
                console.log(dict);
            });
        }
ichbinjay
  • 19
  • 7
  • 1
    Plain objects (what you cal a dictionary) do not have a length property. – VLAZ Aug 05 '22 at 10:19
  • Also, your loop does some asynchronous operation *without waiting for it to finish*. It is guaranteed that when the loop finishes, the async operations are not done yet. So, `dict` will have no properties in it anyway. [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/q/23667086) – VLAZ Aug 05 '22 at 10:21
  • hello @VLAZ, thank you for reaching out. I've tried to implement it using promises, but the dict still exhibits previous behavior. I'll included the new code in the post. Could you please tell me where I'm doing wrong? – ichbinjay Aug 05 '22 at 10:48
  • 1
    Your Promise implementation is wrong: you don't `await` the `get` call so your code doesn't do anything different that the first version. Also try to avoid mixing `async/await` with `.then` – Jared Smith Aug 05 '22 at 11:16
  • 1
    hello @JaredSmith, I've implemented the promise as you've told, and the code works now. Thank you so much for the help! – ichbinjay Aug 05 '22 at 12:54

1 Answers1

1

Basing on comments made by VALZ and JaredSmith, this is the working code:

function dictGenerator(regnos, selectedValue) {
            const get_dict = async () => {
                var dict = {};
                for(let i = 0; i < regnos.length; i++){
                await get(child(dbref, "RegisterNos/" + regnos[i])).then((snapshot)=>{
                    if(Object.keys(snapshot.val()).length-1 == selectedValue){
                        dict[regnos[i]] = snapshot.val()["name"];
                    }
                });
            }
            return dict;
            };

            get_dict().then((dict) => {
                console.log(dict);
            });
        }
}
ichbinjay
  • 19
  • 7