1

I'm quite new to Javascript. I have an array of persons and I want to make an HTTP request for every person and associate the response with the respective person and spit it out. I tried doing:

async function queryData() {
    var persons = ["Alice", "Jerry", "David", "Bob"];
    var parentToAppendTo = document.getElementById("response");
    parentToAppendTo.innerHTML = "<h5> Response: </h5>";
        
    await Promise.all(persons.map(async (person) => {
        postRequest("http://localhost:8000/pay", {
            "pay": person,
        })
        .then(response => response.json())
        .then((data) => {
            parentToAppendTo.innerHTML += 
                "<div>" + person +  "</div>\
                 <div>" + data.success + "</div>";
        })
    }));
    // Do something else after resolving all requests
}

function postRequest(url, data) {
    const options = {
        method: 'POST',
        mode: 'cors',
        cache: 'no-cache',
        credentials: 'same-origin',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(data)
    }
    return fetch(url, options);
}

This is producing different results in different runs. Suppose if the server returns {"success": true} only for Bob and false for everyone else, it would say something like:

"Alice": false
"Jerry": false
"David": false
"Bob": false

or

"Alice": false
"Jerry": true
"David": false
"Bob": false

I have checked Closures and workaround with closures but still couldn't find a way to get around this.

I'm sure that there's no problem from the server-side. It's something about closures regarding data in .then(data => {...}); that's bugging me!

Thanks for the help in advance!

  • What's your code producing? Maybe give us some examples, with what you're expecting, and what's actually happening. – Take-Some-Bytes Oct 18 '20 at 19:42
  • 1
    "This is producing different results in different runs" — This is too vague to really help with. How is it different? Could the server side code be responsible? Can you reproduce the problem if you mock `postRequest`? – Quentin Oct 18 '20 at 19:42
  • 1
    @EmilioGrisolía — No. `map` will just return an array of promises, in order, then `Promise.all` will wait for them all to resolve before continuing. – Quentin Oct 18 '20 at 19:43
  • 1
    Re edit, the only variable being closed over there is `parentToAppendTo` and there's no way that is responsible for different names getting `true` and `false` values. – Quentin Oct 18 '20 at 19:56
  • @Quentin- Is `data` not being closed? I'm just new to JS. Please correct me if I'm wrong – Karthik Chennupati Oct 18 '20 at 20:07
  • 1
    @KarthikChennupati — `data` is a function parameter. It only exists in the innermost function. – Quentin Oct 18 '20 at 20:31
  • Please post the code of `postRequest` – Bergi Oct 18 '20 at 20:41
  • Thanks for the update. Your code really seems fine. "*Suppose if the server returns {"success": true} only for Bob and false for everyone else*" - is that what you think the server should return, or is that what you verified (e.g. using devtools network panel) the server actually returned when you ran this code? – Bergi Oct 18 '20 at 20:58
  • @Bergi The server actually returns (server is also written by me) `{"success": true}` for Bob and `{"success": false}` for everyone else. But, I couldn't display the same. I verified the same using packet sniffer also! – Karthik Chennupati Oct 18 '20 at 21:04

0 Answers0