JavaScript push Array into Array

10,313

Solution 1

i didn't have time to test the code, but it should work this way:

    function requestLocations( addresses, callback ) {
        var remainingLocations = addresses.length;
        var locations = [];

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

            var address=addresses[i]; // the address e.g. 15 Main St, Hyannis, MA

            locations[i] = [];

            geocoder.geocode({ 'address': address}, (
                function(idx) {
                    return function(result) {
                        locations[idx] = [  addresses[idx], 
                                            results[0].geometry.location.hb,
                                            results[0].geometry.location.ib,
                                            idx
                                        ];

                        //decrement the number of remaining addresses
                        --remainingLocations;

                        //if there are no more remaining addresses and a callback is provided then call this calback with the locations
                        if( remainingLocations === 0 && callback ) {
                            callback(locations);
                        }               
                    }; // returns the real callback function for your geocoding

                })(i) //direct invocation of function with paramter i for scoping
            );

        }
    }


    requestLocations(addresses, function( locations ) {
        console.dir(locations);
        console.log(locations.length);
    });

The Problem with your code is the following. First this part of the code is executed:

        var locations = []; // The initial array
        for (var i = 0; i < addresses.length; ++i) {

            var address = addresses[i]; // the address e.g. 15 Main St, Hyannis, MA
            geocoder.geocode({
                'address': address
            }, function(results) {
                //this part is called later when that data is ready (it is an asynchronous callback)

            });
        };

        //because of the async request this is still 0
        console.log(locations.length);

After that the callbacks itself are called as soon as the browser receives the data from the server:

      function(results) {
        var obj = {
            0: address,
            1: results[0].geometry.location.hb,
            2: results[0].geometry.location.ib,
            3: i
        };
        console.log(obj);
        locations.push(new Array());
        locations[i].push(obj);

      }

Solution 2

This should be all you need:

geocoder.geocode({ 'address': address}, function(results){
            locations.push([
              address,
              results[0].geometry.location.hb,
              results[0].geometry.location.ib,
              i //this is actually going to always be 
                //addresses.length because the callback won't fire
                //until well after the loop has completed. 
                //Is this really a necessary field to have 
                //in your array? if so, you'll need to refactor a bit
            ]);
        });
Share:
10,313
rinchik
Author by

rinchik

Updated on June 15, 2022

Comments

  • rinchik
    rinchik almost 2 years

    I'm currently working with Google maps' geocoding and need to create an array that will contain arrays as an elements.

    Basically i need to create this:

        var locations = [
          ['Bondi Beach', -33.890542, 151.274856, 4],
          ['Coogee Beach', -33.923036, 151.259052, 5],
          ['Cronulla Beach', -34.028249, 151.157507, 3],
          ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
          ['Maroubra Beach', -33.950198, 151.259302, 1]
        ];
    

    But dynamically! I need this array to put pins on a map later.

    What I'm doing:

            var locations = []; // The initial array
            for (var i = 0; i < addresses.length; ++i){
    
                var address=addresses[i]; // the address e.g. 15 Main St, Hyannis, MA
                geocoder.geocode({ 'address': address}, function(results){
                    var obj = {
                        0: address,
                        1: results[0].geometry.location.hb,
                        2: results[0].geometry.location.ib,
                        3: i
                    };
                    console.log(obj);
                    locations.push(new Array());
                    locations[i].push(obj);
    
                });
            };
    
            console.log(locations.length);
    

    The problem, question:

    I don't see any errors but at the end locations[] array is empty.

    Here is a console screen if needed:

  • rinchik
    rinchik about 11 years
    Makes sense... but console.log(locations.length); still shows 0
  • canon
    canon about 11 years
    @rinchik probably because geocoder.geocode() is async... and locations hasn't changed by the time you log it.
  • BLSully
    BLSully about 11 years
    See Prinzhorn's comment on your question...it's async, you need to only fire the console.log after all geocodes have been finished
  • t.niese
    t.niese about 11 years
    @BLSully you should mention that i will always be addresses.length because of scoping
  • rinchik
    rinchik about 11 years
    Awesome! :D Just tested it! IT WORKS! Thank you for detailed answer and work on my code :) +1
  • t.niese
    t.niese about 11 years
    @rinchik there was a bug in it addresse should have been addresses[idx] in the callback. please recheck your code, otherwise you will always have the same address in your result.
  • rinchik
    rinchik about 11 years
    Hmm... quick question! for some reason for (var i = 0; i < addresses.length; ++i) loop loops only 12 times and then stops. If i put console.log(remainingLocations); here is the output: screencast.com/t/ENbhFdpaDRcE Do you have any idead why this might be happening?