Difficulty in calling Xmlhttprequest with pure Javascript

Asked

Viewed 38 times

-1

I’m having difficulty a few days, I’m beginner and even reading the documentation sometimes apply is not as simple as it seems, I understand that I lack Exp to understand.

my problem: I’m using the google maps Javascript api and an API I made to load the points (markers) on the map. However, sometimes it loads the map and does not load the dots, I can see this because I used the console.log(marcadores.length) to check and it comes zeroed, then I update the page and everything loads correctly, but can also load empty again.

Could someone please give me a light?

I’d like to call the function initMap() only after loading the array with the data that came from my DB API, how to proceed?

Below is the code I use to load the data from the api:

var marcadores = [];
function carregaPosicoes(){
    var request = new XMLHttpRequest();
    request.open("GET", "http://localhost:5000/Truck/Veiculos", true);
  
    request.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        const data = JSON.parse(this.response);
        data.forEach(veiculo => {
            marcadores.push(veiculo);
            });
        };
    };
    initMap();
    request.send();

};
  • can move initMap(); into the Function onreadystatechange. Here the concept is when running the line request.open the code flow already goes to the next line which is request.onreadystatechange, but this wait line returns from the API, a Promise as we call it, so since there’s nothing yet, go to the next line which is the initMap() and there is still no data, because the call has not yet returned, so you need to move this line inside the Function

  • From what I understand, Voce could call the function init within the if, after the forEach. Tested it that way?

  • @Ricardopunctual 4 seconds faster than I XD

  • 3

    :D was almost instantaneous @Cmtecardeal, not to miss the joke, I was more like "Punctual" ;)

  • Your question has nothing to do with async/await. It has more to do with the object XMLHttpRequest, then I edited the question title.

  • 1

    @Ricardopunctual hahahahah hahaha. Noting that the question has more to do with XMLHttpRequest than async/await

  • @Cmtecardeal, thanks for the editing, is that when I searched on "expect to load object and perform function" always fall into async/await. I will test the suggestions here and go back to comment on what worked. thank you all so far.

  • I added a responsta to demonstrate what @Piovezan replied

Show 3 more comments

2 answers

2

Understand that this function() below is a "callback" (you do not send call directly, only passes the reference of the function to someone who will send to call her when it is the appropriate time for it) and is being declared now but will only be called by the object XMLHttpRequest when the ready state change event occurs, that is, at a time later than when it was declared (when your request (request) for the server API, which takes a while to occur and the code cannot wait, has come to an end, for example), while the initMap() is already being called right after this statement and before the request takes place.

request.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        const data = JSON.parse(this.response);
        data.forEach(veiculo => {
            marcadores.push(veiculo);
            });
        };
    };
    initMap();

Trying to make a translation, the name "onreadystatechange" means "when the change occurs in the 'ready' state, or to the 'ready' state (call me)" and indicates which function will be called when this event occurs. " on<nome-do-evento>" is a common nomenclature for this code situation that reacts to events.

Therefore playing the initMap() to be called inside it must resolve, as it will call when the event occurs and soon after it has populated the map:

request.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        const data = JSON.parse(this.response);
        data.forEach(veiculo => {
            marcadores.push(veiculo);
            });
        };
       initMap();
    };

To learn more:

2


To complement the @Piovezan response, I’ll put together a simple example demonstrating the program flow when you have one callback or Promise.

This piece of script writes on the console the points it passes, 1 in 1. Note that when executing the order it is not the same, because a Function to generate a 1s wait, and simulate an asynchronous call, for example an API:

/////////////// 1
console.log("ponto 1");
var dados = {};

/////////////// 2
console.log("ponto 2");
sleep(1000).then(() => {
    /////////////// 3
    console.log("ponto 3");
    dados.algumaCoisa = "oi";
    
    /////////////// 4
    console.log("ponto 4");
    console.log("dados.algumaCoisa=" + dados.algumaCoisa);
});

/////////////// 5
console.log("ponto 5");
console.log("dados.algumaCoisa=" + dados.algumaCoisa);

function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

/////////////// 6
console.log("ponto 6");

The result of this code is:

ponto 1
ponto 2
ponto 5  <- aqui seguiu o fluxo, pulou os dois pontos que estão na função de callback
dados.algumaCoisa=undefined  <- algumaCoisa ainda não foi definido
ponto 6
ponto 3 <- após 1s, entra no callback
ponto 4
dados.algumaCoisa=oi <- agora algumaCoisa tem valor :)
  • From the little I understand of JS, Promises are a concept very analogous to Futures of Java. Both return a reference to something that has not yet occurred, having this reference now is not very useful but on the other hand it is quite useful to use it to define what will be the callback that will be called after this occurrence (usually to deal with the result returned by the occurrence, as data brought from a remote request). It’s a way of programming event reactivity. But I think you took a little turn in the example, the callback could have been passed straight to setTimeout().

  • But I know you did this to illustrate the Promises, the result is only more complicated to understand (but it is easier when you follow the code in the order that the comments indicate). : ) The utility is demonstrated when you observe that the code that reacts to the event is often linked to the moment when that event is called, so although it occurs at different times it must be together in order to share the same scope.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.