0

I have to save lot of object in my database with mongoose.

Here is an example of my code :

for (var i = 0; i < userdata.length; i++) {

    var newCompany = Company({
      name: userdata[i].company_name
    });

    newCompany.save(function(err, c) {
        if (err) throw err;

        var newGeoloc = Geolocation({
            latitude: userdata[i].latitude,
            longitude: userdata[i].longitude
        });

        newGeoloc.save(function(err, g) {
            if (err) throw err;

        // Create new Office
        var newOffice = Office({
            name        : userdata[i].office_name,
            address     : userdata[i].address,
            city        : userdata[i].city,
            zip_code    : userdata[i].zip_code,
            geolocation : g._id,
            company     : c._id
        });

        // Save the Office
        newOffice.save(function(err, officeCreated) {
            if (err) throw err;

            console.log('Office created!');

        });
    });
}

Why my i variable when I save the geolocation object latitude: datas[i].latitude got the max length of my array userdata.length ? E.g if userdata has 150 object, I'll get always 150 when I create the geolocation object.

How can I do ?

John
  • 4,711
  • 9
  • 51
  • 101
  • Possible duplicate of [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – DAXaholic Sep 16 '16 at 17:09
  • So I just have to use let keyword to make it work ? – John Sep 16 '16 at 19:33

1 Answers1

2

Since the for loop runs without waiting for the callback to be received in the save functions, you can use closures to keep the value of i local to the self invoking function as shown below.

for (var i = 0; i < userdata.length; i++) {
    (
        function(index) {
            var newCompany = Company({
                name: userdata[index].company_name
            });

            newCompany.save(function(err, c) {
                if (err) throw err;

                var newGeoloc = Geolocation({
                    latitude: userdata[index].latitude,
                    longitude: userdata[index].longitude
                });

                newGeoloc.save(function(err, g) {
                    if (err) throw err;
                    var newOffice = Office({
                        name        : userdata[index].office_name,
                        address     : userdata[index].address,
                        city        : userdata[index].city,
                        zip_code    : userdata[index].zip_code,
                        geolocation : g._id,
                        company     : c._id
                    });

                    // Save the Office
                    newOffice.save(function(err, officeCreated) {
                        if (err) throw err;
                        console.log('Office created!');
                    });
                });

           });
        }
    )(i);
}

When the self invoking function is called each time the loop is run, the value of i is copied to the variable index.

Ananth Pai
  • 1,939
  • 14
  • 15
  • I have to create a function for each save in my loop ? In my loop I have 4 save – John Sep 19 '16 at 07:48
  • I need to reuse the company and geolocation object to insert the object id in the office object – John Sep 19 '16 at 08:19
  • I have edited the code, try using the modified code, it should work without any issues – Ananth Pai Sep 19 '16 at 08:27
  • It works thanks :). But is there another syntax to write this anonymous function ? `( function(index) { }(i)` it's very strange – John Sep 19 '16 at 09:31
  • Rather than use an anynomous function, you can use a normal function. The code would be something like this `(saveCompanyData(index);)(i)`. The code logic would now be inside the `function saveCompanyData(index)` – Ananth Pai Sep 19 '16 at 09:46
  • Ok so this `(i)` is required ? – John Sep 19 '16 at 09:54
  • Yes, you are passing the value of `i` to the inner function, that's how closures work. – Ananth Pai Sep 19 '16 at 09:57