0

So I am populating an array within a function but when i call on that array outside of the function im pretty sure it comes out as a string. The array works fine inside the function when I try to call [1] but if I try to do that outside the function it comes up as undefined.

Hope someone can help me out as i am almost finished this code but this is stopping me, thanks.

Just for reference in case its helpful, when I console log outside the function it comes up like this:

[]
0: 7604
1: 7606
2: 7607
3: 7608

Then within the function like this:

(4) [7604, 7606, 7607, 7608]
0: 7604
1: 7606
2: 7607
3: 7608

Here is also the code, I have removed the token for security purposes also ignore some parts of the code like posturl as they will be used once I have figured this out:

var geturl = "https://api.sendgrid.com/v3/asm/suppressions/ibrarr2000@gmail.com";
var posturl = "https://api.sendgrid.com/v3/asm/groups/"+  +"/suppressions";
var deleteurl = "https://api.sendgrid.com/v3/asm/groups/"+  +"/suppressions/ibrarr2000@gmail.com";
var token = "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";
let headers = new Headers();
let myData = {};
headers.append('Authorization', 'Bearer ' + token);
//supressionids = new Array();
var supressionids = [];

fetch(geturl, {
 method: 'GET',
 headers: headers,
}).then(function (res) {
    return res.json();
}).then(function (data) {
    myData = data;
    buildSelect(data);
});

function buildSelect(d) {
    let select = document.createElement('form');
    d.suppressions.forEach(function (item) {
        let label = document.createElement('label');
        let option = document.createElement('input');
        option.value = item.suppressed;
        option.type = "checkbox";
        option.setAttribute("onclick","task(event);");
        option.id = item.id;
        option.classList = "subbox";
        option.textContent = item.name;
        label.textContent = item.name;
        select.appendChild(label);
        select.appendChild(option);

        supressionids.push(item.id);

        let br = document.createElement('br');
        select.appendChild(br);

        if(JSON.stringify(item.suppressed) == 'false'){
            option.setAttribute("checked", "checked");
            }
    });
    document.querySelector('body').appendChild(select);

    console.log(supressionids);

}

console.log(supressionids);

function task(e) {
  if(e.target.checked){
    fetch(deleteurl, {
         method: 'DELETE',
         headers: headers,
        });
  } else {
    fetch(posturl, {
      method: 'POST',
      body: JSON.stringify({ "recipient_emails": [ "ibrarr2000@gmail.com" ] }),
      headers: headers,
      });
  }
}
  • 1
    I think you are trying to get the array values before the `GET request` is done. – eag845 Dec 07 '18 at 16:18
  • @eag845 Thats how this api works mate, 100% sure that not the issue the GET request works fine, and as mentioned the post and delete will be used later on, all i want to do is populate the array supressionids and then continue to use that array outside the function but it seems impossible – Ibrarr Khan Dec 07 '18 at 16:29
  • eag845 is not saying the GET isn't working. He's saying the code hits that `console.log` outside the function before the data has been returned - the code doesn't wait to run it. What you want to do is use a function to contain all the code to be run in your final `.then()` that replaces `buildSelect`. Inside that function, call `buildSelect` and run the rest of your code. – brouxhaha Dec 07 '18 at 16:40
  • @eag845 I will try this out, could you do the code and show me exactly how i should be running the code, i have also added a token so you can test it for yourself – Ibrarr Khan Dec 07 '18 at 16:48

1 Answers1

0

The problem is the GET takes some time to get the data. While the data is being retrieved, the code moves on to the next piece, which is the console.log in the same scope. Use a function to contain all the code you want to run. Change your fetch to this:

fetch(geturl, {
    method: 'GET',
    headers: headers,
}).then(function (res) {
    return res.json();
}).then(function (data) {
    myData = data;
    runCode(data);
});

Then add a containing function:

function runCode(data){
    buildSelect(data);
    console.log(supressionids);
}

Your other option is to contain all the code inside the .then() call or use multiple .then() calls.

brouxhaha
  • 4,003
  • 1
  • 19
  • 22
  • This worked exactly as I wished, thanks for your help. – Ibrarr Khan Dec 10 '18 at 09:21
  • Actually, it almost does sorry, when I put the taske function in the run code function it says task is undefined, and I can't seem to call that function if i put it out the runcode? How would i call this? – Ibrarr Khan Dec 10 '18 at 09:27