Question

First post here, so apologies if I get things wrong...

I'm creating some standalone code to read a folder structure and return all .mp3 files in an Array. Once this has been returned I then loop through the array and for each item I create a Mongoose Object and populate the fields, before saving the object with .save()

I am looping through the array using async.forEach - and while it does loop through all items in the Array they do not save, and there is no error produced to help me identify what is wrong.

If I move the logic of the loop elsewhere then the MP3s are stored in the mongodb database - if I have the example shown nothing is saved.

var saveMP3s = function(MP3Files, callback) {
  console.log('start loop -> saving MP3s');
  async.forEach( MP3Files, function(mp3file, callback) {
    newTrack = new MP3Track();
    newTrack.title = mp3file.title;
    newTrack.track = mp3file.track;
    newTrack.disk = mp3file.disk;
    newTrack.metadata = mp3file.metadata;
    newTrack.path = mp3file.path;
    console.log('....:> Song Start: ');
    console.log(newTrack.title);
    console.log(newTrack.track);
    console.log(newTrack.disk);
    console.log(newTrack.metadata);
    console.log(newTrack.path);
    console.log('....:> Song End: ');
    newTrack.save(function (err) {
      if (err) {
        console.log(err);
      } else {
        console.log('saving Track: '+ newTrack.title);
        callback();
      }
    });
  }, function(err) {
    if (err) { console.log(err); }
  });
  console.log('end loop -> finished saving MP3s');
};

The trouble I have is that when the code is NOT in the async loop the code works and the MP3 is saved in the MongoDB database, inside the async code nothing is saved and no errors are given as to why.

I did try (in an earlier incarnation of the code) create the objects once I had read the metadata of the MP3 files - but for some reason it would not save the last 2 objects in the list (of 12)... So I've rewritten it to scan all the items first and then populate mongoDB using mongoose from an array; just to split things up. But having no luck in finding out why nothing happens and why there are no errors on the .save()

Any help with be greatly appreciated.

Regards, Mark

Was it helpful?

Solution 2

SOLVED

Hi,

I ended up solving it by having the async loop higher up the in the logic so the saveMP3s function was called from within the async loop itself.

Thank you all for your thoughts and suggestions.

Enjoy your day.

mark (not allowed to Accept my answer until tomorrow, so will update the question status then)

OTHER TIPS

var saveMP3s = function(MP3Files, callback) {
  console.log('start loop -> saving MP3s');
  async.forEach( MP3Files, function(mp3file, callback) {
    var newTrack = new MP3Track(); // <--- USE VAR HERE
    newTrack.title = mp3file.title;
    newTrack.track = mp3file.track;
    newTrack.disk = mp3file.disk;
    newTrack.metadata = mp3file.metadata;
    newTrack.path = mp3file.path;
    console.log('....:> Song Start: ');
    console.log(newTrack.title);
    console.log(newTrack.track);
    console.log(newTrack.disk);
    console.log(newTrack.metadata);
    console.log(newTrack.path);
    console.log('....:> Song End: ');
    newTrack.save(function (err) {
      if (err) {
        console.log(err);
      } else {
        console.log('saving Track: '+ newTrack.title);
        callback();
      }
    });
  }, function(err) {
    if (err) { console.log(err); }
  });
  console.log('end loop -> finished saving MP3s');
};

I suspect that the missing var keyword is declaring a global variable and you are overriding it on each iteration of the loop. Meaning, before the first newTrack can complete it's async save operation, you've already moved on in the loop and overridden that variable with the next instance.

Also, in async.forEach you MUST invoke the callback when the operation is completed. You are only calling it if the record saves successfully. You should also be calling it if an error occurs and pass in the error.

Finally, the callback argument to your saveMP3s function never gets called at all. The call to callback() inside the newTrack.save function only refers to the callback argument passed into the anonymous function by async.forEach.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top