0

I have a map that I created to store several instances of a custom class I wrote. If I do a simple console.log(myMapName), I see the details in the output. I see the six entries in my map, I see the key values I stored them under, and then for each entry, I can expand it and see the internals of that instance of my custom class, including the stored values for each attribute in that class definition.

But if I try to use for(let[key,value] of myMapName) to loop over the instances of my class stored as entries in my map and write the key and value of each one to the console using console.log, I see nothing. I can't even get it to at least log the key value for each entry. I would not be surprised if I was doing something wrong to cause it not to log the details of the value of each entry, but the fact that it also refuses to at least list the key value stumps me.

I should mention that I am able to loop over a small test map I created and get the key and value output in the log. Shown here below:

// test map definition

  let myMap = new Map();
  myMap.set('First',{name: 'John', age: '34'})
  myMap.set('Second',{name: 'Mary', age: '24'})

// I can loop over this simple map

  console.log(myMap)

  for(let [key,value] of myMap){
    console.log('key: ' + key)
    console.log('value.name: ' + value.name)
    console.log('value.age: ' + value.age)
  }

// log output for above

enter image description here

 // but using the same loop structure for my map doesn't work

  for(let [key,value] of mgroups){
    console.log('key: ' + key)
    console.log('value: ' + value)
    console.log('value.name: ' + value.name)
  }

Edit: adding my class' code and a pic of its log output. the loop code is shown already above:

class MaterialGroup {

  constructor(name){
    this.name = name;
    this.alias = name;
    this.usemtl = "";
    this.faces = [];
    this.indices = [];
    this.vertices = [];
  }

setName(name){ this.name = name; }
getName(){ return this.name; }

setGroupIndices(){}
getGroupIndices(){}

setGroupVertices(){}
getGroupVertices(){}

}

module.exports = MaterialGroup

Sample of log output of console.log(mgroups):

enter image description here

Edit#2: below is the function where I use node.js' fs module's readline to to read in a file and populate the instances of my custom class (shown above) and then add each to the mgroups map. This is done and completed before the attempt to loop mentioned in the question but might be where the async issue I am seeing is introduced. This method gets called to read in the data and populate the mgroups map and then right after that another method is called to loop over it.

function readObjFile(objFilePath){

      var objInput = fs.createReadStream(objFilePath);

      var rl = require('readline').createInterface({
        input: objInput,
        terminal: false
      });

      ...

      let mgroup = new MaterialGroup("NotSet");


      rl.on('line', function(line){

        var pieces = line.split(" ");

        ...

        // section of function that works with MaterialGroup class that
        // gets added to my mgroups map using .set calls

        if(pieces[0] == "g"){

          var mpieces = pieces[1].split("_");

          if(processing == "mgroups"){

            mgroups.set(mgroup.name, mgroup);
            mgroup = new MaterialGroup(mpieces[mpieces.length - 1]);

          } else {

            processing = "mgroups";
            mgroup = new MaterialGroup(mpieces[mpieces.length - 1]);

          }

        }

        if(pieces[0] == "usemtl"){
          mgroup.usemtl = pieces[1];
        }

        // this is new f block for material group faces
        if(pieces[0] == "f"){
          mgroup.faces.push([pieces[1]-1,pieces[2]-1,pieces[3]-1]);
          mgroup.indices.push(pieces[1]-1);
          mgroup.indices.push(pieces[2]-1);
          mgroup.indices.push(pieces[3]-1);
          mgroup.vertices.push(vertices[pieces[1]]);
          mgroup.vertices.push(vertices[pieces[2]]);
          mgroup.vertices.push(vertices[pieces[3]]);
          indices.push(pieces[1]-1);
          indices.push(pieces[2]-1);
          indices.push(pieces[3]-1);
        }

        if(pieces[0] == "eof"){
          mgroups.set(mgroup.name, mgroup);
        }

      }).on('close', () => {

        ...

        setMgroupsMap(mgroups);

      });

}

I can do a simple console.log(mgroups) and see all of the entries and their details but I can't loop over them one by one.

One thing that caught my attention is that even in the log where I can see the six entries and their details, it shows Map(0) at the top of that log entry. This makes no sense to me since in the details below the six entries I see the size entry for the map and there it shows a value of 6.

Does anyone know of a detail has to be addressed when attempting to loop over the entries of a map that are instances of a custom class definition? I think this is the root cause since the only other difference I notice between my output and a test output I did of a simple make using standard object entries like {'name':'John', 'age':'34'} (aside from the fact that this test map showed the correct size of Map(2) at the top of its log output) was that for my map it shows {"KeyValue" => MyCustomClassName} and the simple test map just shows {"KeyValue" => Object}.

I'm sure I'll get a lot of "this has been asked" quick replies, but I have looked at this from many angles and tried a lot of different ways to loop it and have gotten nowhere, and I have tried looking at many other posted questions but they did not help. So, thanks to anyone who takes the time to provide a helpful reply.

user3064141
  • 407
  • 4
  • 17
  • 1
    What is `mgroups` in the code that does not work? Please post a complete [mcve] – Bergi Jul 06 '22 at 21:02
  • Very difficult to make progress when "my custom class" is a black box. Agree with @Bergi we need more. – David P. Caldwell Jul 06 '22 at 21:02
  • "*it shows Map(0) at the top of that log entry.*" - that suggest you are filling the map *after* logging and iterating it. See [Is console.log() async or sync?](https://stackoverflow.com/q/23392111/1048572) – Bergi Jul 06 '22 at 21:04
  • thanks for the link. I did look at that one but since I was able to dump the whole map to log just above this looping issue I didn't think it was an async issue but maybe it is and I just don't see it. I will try to do as you ask and add an example of my class or its log output. – user3064141 Jul 06 '22 at 21:08
  • Yes it is. See also the description you get when hovering over the `[i]` icon in the console. – Bergi Jul 06 '22 at 21:11
  • ok. I did mouse over the [i] before and noticed the "value below was evaluated just now" but didn't know what to make of its since I had previously stored my map entries. I will look into the async/sync issue further. thanks – user3064141 Jul 06 '22 at 21:14
  • 1
    Please post the actual code that is constructing / filling the map, logging, and iterating it. – Bergi Jul 06 '22 at 21:16
  • Just added my class definition and a pic showing log output below that when I dump the whole map to log. thanks – user3064141 Jul 06 '22 at 21:27
  • Yes, that's the output you already described. You still didn't post the code the fills `mgroups` though. – Bergi Jul 06 '22 at 23:21
  • @Bergi I've added the method where the mgroups map gets populated with instances of my custom class. This method gets called to populate the mgroups map and then after that I call another method where I attempt to loop over mgroups and is where I am seeing the issue. Thanks. – user3064141 Jul 07 '22 at 13:10
  • Yeah, that code is definitely asynchronous. Are you using `mgroups` only in the `close` event handler, i.e. from that `setMgroupsMap(mgroups)` call? Can you try to add the looping and logging code right in there, instead of "*after that I call another method*"? Or do you mean `setMgroupsMap` by that "*other method*"? – Bergi Jul 07 '22 at 13:22
  • Thanks for the suggestion. I will look into that. I think the answer to your question is yes, meaning from the point where I call that set method to the point where I call the next follow-up method (where I see the looping issue) nothing else is done to mgroups, so your suggestion makes sense. Thanks. – user3064141 Jul 07 '22 at 13:32

1 Answers1

-1

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
}

let mgroups = new Map()
mgroups.set('First', new Person('John', '34'))
mgroups.set('Second', new Person('Mary', '24'))

for (let [ key, value ] of mgroups) {
  console.log('key: ' + key)
  console.log('value: ' + value)
  console.log('value.name: ' + value.name)
  console.log('value.age: ' + value.age)
}
lukas.j
  • 6,453
  • 2
  • 5
  • 24