2

I'm new on StackOverflow :)

I need help: I'm trying to make an inverse geocode (get an address from coordinates). I have a good URL that works with an ajax. I have many coordinates to convert to address, that is why I'm trying firstly on an array with 4 coordinates on JSfiddle.

What I want for the result is that my script adds all the addresses to my array. I'm trying with a for loop, and on each element of the array, an ajax call which finds the good coordinates.

You can find the call on this link (i put the script after the link) : https://jsfiddle.net/e2wr3umy/

my code which works for an element:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
$.ajax({

                     url: 'https://reverse.geocoder.ls.hereapi.com/6.2/reversegeocode.json',
                      type: 'GET',
                      dataType: 'jsonp',
                      jsonp: 'jsoncallback',
                      data: {
                        prox: '43.564624, 3.847154,250',
                        mode: 'retrieveAddresses',
                        maxresults: '1',
                        gen: '9',
                        apiKey: 'NOT_THE_REAL_API_KEY'
                      },
                      success: function (data) {
                        var re = JSON.stringify(data);
                        console.log(data);
                        var num = (data.Response.View[0].Result[0].Location.Address.HouseNumber);
                        var rue = (data.Response.View[0].Result[0].Location.Address.Street);
                        var ville = (data.Response.View[0].Result[0].Location.Address.City);
                        var CP = (data.Response.View[0].Result[0].Location.Address.PostalCode);
                        console.log(num, rue, CP, ville)
                      }
                    });

Then, I'm trying on an array of 4 elements, this is the link: https://jsfiddle.net/L07pjwba/

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>

var adresse = [['43.564624, 3.847154',1],['43.564624, 3.447154',27],['43.64624, 3.727154',75],['43.564624, 3.617154',254]];


for (i =0; i<adresse.length; i++) {
console.log("element", adresse[i]);
$.ajax({
                      url: 'https://reverse.geocoder.ls.hereapi.com/6.2/reversegeocode.json',
                      type: 'GET',
                      dataType: 'jsonp',
                      jsonp: 'jsoncallback',
                      data: {
                        prox: adresse[i][0].concat(', 250'),
                        mode: 'retrieveAddresses',
                        maxresults: '1',
                        gen: '9',
                        apiKey: 'NOT_THE_REAL_API_KEY'
                      },
                      success: function (data) {
                        var re = JSON.stringify(data);
                        console.log("data", data);
                        var num = (data.Response.View[0].Result[0].Location.Address.HouseNumber);
                        var rue = (data.Response.View[0].Result[0].Location.Address.Street);
                        var ville = (data.Response.View[0].Result[0].Location.Address.City);
                        var CP = (data.Response.View[0].Result[0].Location.Address.PostalCode);
                        adresse[i].push(num, rue, ville, CP);

                      }
                    });

}
console.log("adresse : ",adresse);

But the result is not what I expect: it looks like the ajax call starts after the end of the for loop, even if it is inside the for a loop. I tried with async: false in the ajax, but it didn't change anything.

4
  • So you are saying the result you get is empty right? Have you seen javascript promises? Commented Feb 27, 2020 at 10:00
  • Sorry, i mean the result i get in the console.log is not what i expected Commented Feb 27, 2020 at 10:02
  • could you address me on what you're getting instead of what? Commented Feb 27, 2020 at 10:04
  • The first link returns "undefined undefined 34430 Saint-Jean-de-Védas" and it's what i expect. But on the second link, i'm getting an error, I get in the consoe.log "element Array [ "43.564624, 3.847154", 1 ]" 4 fimes, then " adresse : Array(4) [ (2) […], (2) […], (2) […], (2) […] ] " and after this TypeError: adresse[i] is undefined 4 times. I'd like the ajax calls before the return of adress, and adress completed. Commented Feb 27, 2020 at 10:12

1 Answer 1

4

This is a common problem stemming from not understanding async. Here is a canonical resource for async issues, but I don't think it would resolve all of your problems, so I won't mark it as a duplicate, but please read it.

Basically, your code tells the geocoding service to let you know about the addresses. Then you print the array. Some time in the future, the geocoding service answers you, but the array is already printed, and JavaScript doesn't have a time machine.

The basic principle is, you can never use the value you obtain from an async function anywhere except in a callback to that function (or its promise chain), and functions that are called from there. In your first snippet you do it correctly: you use console.log inside the callback. In the second snippet, you move it outside the callback, and that is the source of your problems.

Here is how to write it correctly. $.ajax returns a "promise", which you can chain using .then, to specify that something should be done when the promise is fulfilled (i.e. you get a response from the geocoding service). You can use Promise.all to wait for all the promises in an array to be fulfilled. All together, it should look like this (I changed the minimal amount of your code, I'd write it a little bit differently):

var adresse = [
  ['43.564624, 3.847154', 1],
  ['43.564624, 3.447154', 27],
  ['43.64624, 3.727154', 75],
  ['43.564624, 3.617154', 254]
];

var promises = [];
for (i = 0; i < adresse.length; i++) {
  console.log("element", adresse[i]);
  var promise = $.ajax({
    url: 'https://reverse.geocoder.ls.hereapi.com/6.2/reversegeocode.json',
    type: 'GET',
    dataType: 'jsonp',
    jsonp: 'jsoncallback',
    data: {
      prox: adresse[i][0].concat(', 250'),
      mode: 'retrieveAddresses',
      maxresults: '1',
      gen: '9',
      apiKey: 'NOT_THE_REAL_API_KEY'
    },
  }).then(function(data) {
    var num = (data.Response.View[0].Result[0].Location.Address.HouseNumber);
    var rue = (data.Response.View[0].Result[0].Location.Address.Street);
    var ville = (data.Response.View[0].Result[0].Location.Address.City);
    var CP = (data.Response.View[0].Result[0].Location.Address.PostalCode);
    adresse[i].push(num, rue, ville, CP);
  });
  promises.push(promise);
}

Promise.all(promises).then(function() {
  console.log("adresse : ", adresse);
});
Sign up to request clarification or add additional context in comments.

1 Comment

Okay Thank you for your answer, i will try to find with promises and .then . Nice day to you :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.