6

I'm using Node.js to loop through an array of Artist results I obtain from Mongoose:

User.find({UserType: "Artist"}, '_id Firstname BIO list_artworks').then((artists) =>{
    for (var i=0; i < artists.length; i++){
        console.log(artists[i]);
    }
})

The above code works find and prints out all three properties of Artists that I asked for.

EDIT: Here's an example of what I see in console:

{
    _id: 'T8fdSmf0e1ua',
    BIO: 'This is Susan's bio...\n',
    Firstname: 'Susan',
    list_artworks: [
        'ID ONE',
        'ID TWO', 
        ...
    ]
}

However, when I try to access a property that is an array of Artwork ids, everything is undefined using console.log():

for (var i=0; i < artists.length; i++){
    console.log(artists[i].list_artworks);
}

When I access the other properties of my Artist, like BIO or Firstname, it prints successfully to my console:

for (var i=0; i < artists.length; i++){
    console.log(artists[i].BIO);
}

Why is this the case? I don't think it has to do with async code in this case given that all objects are return in the then() chain. The list_artworks property is clearly there if I print the entire artist object, but why is it undefined when I attempt to access it?

Here's another example. I print out each property, and then the object itself:

console.log(artist.BIO);
console.log("---------------")
console.log(artist.Firstname);
console.log("---------------")
console.log(artist.list_artworks);
console.log("---------------")
console.log(artist)

And here's what is printed on my console:

 
---------------
Mike
---------------
undefined // <--- when I access the property itself
---------------
{
  _id: '599asdsdasd232d23d2',
  Firstname: 'Mike',
  BIO: '',
  list_artworks: // <-- why does it show up here?
   [ '6cohpx7d23asu',
     'W4Fgs23X5aXds',...

Here is my entire code base:

setTimeout(function(){

     User.find({UserType: "Artist"}, '_id Firstname BIO list_artworks').then((artists) =>{
         console.log(artists.length);

        for (var i=0; i < artists.length; i++){
            artist = artists[i];
             console.log(artist.BIO);
             console.log("---------------")
             console.log(artist.Firstname);
             console.log("---------------")
            console.log(artist['list_artworks']);
             console.log("---------------")
             console.log(artist)
            }
        }

     ).catch((err)=>{console.log(err)});
}, constants.NLP_TRAINING_INTERVAL);
Yu Chen
  • 6,540
  • 6
  • 51
  • 86
  • Are you sure that all of the objects you're getting from MongoDB have a `list_artworks` key on them? – Sean Parsons Jul 08 '17 at 17:08
  • @SeanParsons Yes. I edited my question to include my console.log. There's only three Artists objects in my sandbox DB and they all have that key. – Yu Chen Jul 08 '17 at 17:13
  • Strange that the output starts with `----------`, as that is not the first thing you print... – trincot Jul 08 '17 at 17:33
  • @trincot that's because Mike's BIO is empty so it actually did print that line. Just when StackOverflow formatted my output, it cut that text off since it was empty. – Yu Chen Jul 08 '17 at 17:34
  • Is there *any* other code that could have added the `list_artwork` property later? – trincot Jul 08 '17 at 17:35
  • @trincot No I don't think so. But I've posted the entire code base as an edit just in case. – Yu Chen Jul 08 '17 at 17:41
  • I just would like to exclude one thing, since it is a known fact that when you `console.log` an object, and then look at it in dev tools, the properties that are revealed are those that were retrieved by devtools asynchronously, so seeing them there is no guarantee about what was there when the `console.log` was made. Could you do in the loop a `console.log(JSON.stringify(artist, null, 2));` and see what you get? – trincot Jul 08 '17 at 17:48
  • console.log(artist.list_artworks); -- change this line to console.log(artist["list_artworks"]); – Tomasz Bubała Jul 08 '17 at 17:50
  • @trincot I get back a valid JSON object with list_artworks returning the correct IDs. – Yu Chen Jul 08 '17 at 17:54
  • This is puzzling. Can you verify there is no spelling problem with `list_artworks`, some Unicode characters that look alike, hidden short spaces, etc... – trincot Jul 08 '17 at 17:58
  • @trincot I've asked the other developer who created the schema and DB if he has any insight into this. I don't see any strange characters or formatting with that field. Will keep you updated. – Yu Chen Jul 08 '17 at 18:05
  • @trincot check the accepted answer. I guess next on my reading list is this post: https://stackoverflow.com/questions/31467031/whats-the-difference-between-node-element-object. I thought I already WAS returning an object but apparently element != object. – Yu Chen Jul 08 '17 at 19:07
  • Glad it got solved (+1 on Q&A)! – trincot Jul 08 '17 at 20:23

3 Answers3

5

Call toObject on the artist:

artist = artists[i].toObject();
Andy Gaskell
  • 31,495
  • 6
  • 74
  • 83
  • This works! Thank you! I took a look at the documentation for toObject() but still am not fully sure why this works- isn't calling artists[i] just returning the ith element (an object) of the array? – Yu Chen Jul 08 '17 at 19:06
  • 1
    `artists[i]` is a mongoose document, not a regular JS object; calling `toObject` converts the document into an object. – Andy Gaskell Jul 08 '17 at 19:20
0

Try this:

User.find({UserType: "Artist"}, '_id Firstname BIOlist_artworks').then((artists) =>{
             var index = i.toString();
            console.log(artists[index][‘list_artworks’]);
        }
   }
phd
  • 82,685
  • 13
  • 120
  • 165
-1

Try this

User.find({UserType: "Artist"}, '_id Firstname BIO list_artworks').then((artists) =>{

        for (var i=0; i < artists.length; i++){
            console.log(artists[i][‘list_artworks’]);
        }
         }
Shanil Fernando
  • 1,302
  • 11
  • 13