Search code examples
javascriptcookies

setCookie() not working inside a fetch in javascript


I have a Javascript code that fetch and API and fill a table. I also need to save and read cookies to indicate if the data fetched are now or no.

I have an issue with the cookies. Setting cookies inside the for loop and fetch.then seems to set always a single cookie with an undefined name.

As you can see from the code, name of the cookie is always different and always a string

I'm using Chrome v 126.0.6478.62 64bit and Live Server extension of VSCode

Why is that happening?

If I manually set the cookie with setCookie("a", 62, 365) it works

const project_ids = [62, 37, 43, 67, 29];
const project_name = ["a", "b", "c", "d", "e"];

for (i = 0; i < project_ids.length; i++) {
      let v_aria = document.getElementById("v-" + project_name[i]);
      let aria_collapse = document.getElementById(
        project_name[i] + "-collapse"
      );
      let aria_link = document.getElementById(project_name[i] + "-link");
      let aria_data = document.getElementById(project_name[i] + "-data");
      fetch(
        "https://<my_domain>/api/v4/projects/" +
          project_ids[i] +
          "/releases",
        {
          method: "GET",
          headers: {
            "PRIVATE-TOKEN": GITTOKEN,
          },
        }
      )
        .then((response) => response.json())
        .then((json) => {
          v_aria.innerHTML = json[0]["name"];
          //aria_collapse.innerHTML = json[0]["description"];
          let link = json[0]["_links"].self;
          aria_link.innerHTML = '<a href="'.concat(
            link,
            '" target="_blank">Prject</a>'
          );
          aria_data.innerHTML = json[0]["released_at"];
          let cookie = getCookie(project_name[i]);
          if (cookie != json[0]["name"]) {
            v_aria.classList.add("bg-warning");
            setCookie(project_name[i], json[0]["name"], 365);
          }
        })
        .catch(function (error) {
          // handle error
          console.log(error);
          v_aria.innerHTML = "Error";
          v_aria.classList.add("text-danger");
          setCookie(project_name[i], "None", 365);
        });
    }

Basically the code add the data fetched on the API to the table and, if the data fetched are different from the one saved on the cookie, change the background colour.

To set and get the cookie I use the functions of W3School

function setCookie(cname, cvalue, exdays) {
  const d = new Date();
  d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
  let expires = "expires=" + d.toUTCString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

function getCookie(cname) {
  let name = cname + "=";
  let decodedCookie = decodeURIComponent(document.cookie);
  let ca = decodedCookie.split(";");
  for (let i = 0; i < ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) == " ") {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

Solution

  • Thanks to @ivar tip, the issue was that the variable i wasn't set correctly:

    for (let i = 0; i < project_ids.length; i++)
    

    Notice the add of let i