1

I know this question has been asked before, but I tried to apply the answers with no results.

I'm trying to do multiple requests on the same domain with a for loop but it's working only for the last record of my array. When I try with only one request it works fine. I don't understand.

Here is the code I use :

var xhr = new XMLHttpRequest();
var idArray = ['1', '2', '3', '4', '5'];

for(var i = 0;i < idArray.length;i++) {
    xhr.open('PUT', 'https://www.domain.com/url/' + idArray[i]);
    xhr.setRequestHeader('Authorization', authorizationToken);
    xhr.send(null);
    var test = setInterval(function () {
        if(xhr.readyState != 4) {
            //someCode
        } else {
            clearInterval(test);
        }
    }, 1000);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            if(xhr.status != 200) {
                //someCode
            }
        }
    }
}

I've also tried this but still no results:

var xhr = new XMLHttpRequest();
var idArray = ['1', '2', '3', '4', '5'];

for(var i = 0;i < idArray.length;i++) {
    (function(i) {
        xhr.open('PUT', 'https://www.domain.com/url/' + idArray[i]);
        xhr.setRequestHeader('Authorization', authorizationToken);
        xhr.send(null);
        var test = setInterval(function () {
            if(xhr.readyState != 4) {
                //someCode
            } else {
                clearInterval(test);
            }
        }, 1000);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if(xhr.status != 200) {
                    //someCode
                }
            }
        }
    })(i);
}

I'm not seeing what I'm doing wrong.

1 Answer 1

3

Your second attempt is fairly close, but you need to create a separate XMLHttpRequest object for each request, within the inline-invoked function expression, see the relocated line with the *** comment:

var idArray = ['1', '2', '3', '4', '5'];

for(var i = 0;i < idArray.length;i++) {
    (function(i) {
        var xhr = new XMLHttpRequest(); // ***
        xhr.open('PUT', 'https://www.example.com/url/' + idArray[i]);
        xhr.setRequestHeader('Authorization', authorizationToken);
        xhr.send(null);
        var test = setInterval(function () {
            if(xhr.readyState != 4) {
                //someCode
            } else {
                clearInterval(test);
            }
        }, 1000);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if(xhr.status != 200) {
                    //someCode
                }
            }
        }
    })(i);
}

Technically, since you don't use i anywhere in the callbacks you're creating in there, you don't need to pass i in and take it as a parameter to the IIFE (but with that ES5-level syntax, you do need the IIFE so that you have separate xhrs).

In ES2015+, there's no need for the IIFE anymore, just use let and const:

const idArray = ["1", "2", "3", "4", "5"];

for (const id of idArray) {
    const xhr = new XMLHttpRequest();
    xhr.open("PUT", "https://www.example.com/url/" + id);
    xhr.setRequestHeader("Authorization", authorizationToken);
    xhr.send(null);
    const test = setInterval(() => {
        if (xhr.readyState !== 4) {
            //someCode
        } else {
            clearInterval(test);
        }
    }, 1000);
    xhr.onreadystatechange = () => {
        if (xhr.readyState == 4) {
            if (xhr.status !== 200) {
                //someCode
            }
        }
    };
}

These days I'd probably use fetch instead of XHR as well.


Side note: Not sure what the interval timer is for there, so I've left it, but your onreadystatechange handler will get called, no need to back it up with a timer.

Sign up to request clarification or add additional context in comments.

2 Comments

For those who (like me) don't know: IIFE = (Immediately Invoked Function Expression)
@DavideAndrea - Sorry, I really shouldn't have just used the acronym there. I've updated and modernized the answer. :-)

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.