0

I'm having problem with loading from local storage.

Here's a part of the code

const getTerminus = () => {
  let terminus;
  if (localStorage.getItem("terminus") === null) {
    terminus = [];
  } else {
    terminus = JSON.parse(localStorage.getItem("terminus"));
  }

  let directions;
  if (localStorage.getItem("directions") === null) {
    directions = [];
  } else {
    directions = JSON.parse(localStorage.getItem("directions"));
  }

  terminus.forEach(async(stop) => {
    let API_URL =
      "https://ckan.multimediagdansk.pl/dataset/c24aa637-3619-4dc2-a171-a23eec8f2172/resource/d3e96eb6-25ad-4d6c-8651-b1eb39155945/download/stopsingdansk.json";
    let response = await fetch(API_URL);
    let data = await response.json();

    const {
      stops,
      stopId,
      stopName,
      stopCode,
      zoneId
    } = data;

    let input = stop;
    let ID;
    let dataArr = [];

    for (let i = 0; i < stops.length; i++) {
      if (
        stops[i].stopName === input &&
        stops[i].stopCode === directions[terminus.indexOf(input)] &&
        stops[i].zoneId === 1
      ) {
        ID = stops[i].stopId;

        dataArr = [ID, stops[i].stopName];
      }
    }

    API_URL = `https://ckan2.multimediagdansk.pl/delays?stopId=${ID}`;

    response = await fetch(API_URL);
    data = await response.json();

    const {
      delay,
      estimatedTime,
      routeId,
      headsign
    } = data;

    let times = [];
    let routeIds = [];
    let headsigns = [];
    for (let i = 0; i < delay.length; i++) {
      times.push(delay[i].estimatedTime);
      routeIds.push(delay[i].routeId);
      headsigns.push(delay[i].headsign);

    }
    routeIds.push(" ");
    times.push(" ");

    const cardDiv = document.createElement("div");
    cardDiv.classList.add("card");

    const stopNameDiv = document.createElement("div");
    stopNameDiv.classList.add("stop-name-div");
    cardDiv.appendChild(stopNameDiv);

    const stopNameSpan = document.createElement("span");
    stopNameSpan.innerText = dataArr[1];
    stopNameSpan.classList.add("stop-name-span");
    stopNameDiv.appendChild(stopNameSpan);

    const scheduleDiv = document.createElement("div");
    scheduleDiv.classList.add("schedule-div");
    cardDiv.appendChild(scheduleDiv);

    if (headsigns.length !== 0) {
      routeIds.unshift("Line");
      headsigns.unshift("Direction");
      times.unshift("Departure");
    }

    const lineSpan = document.createElement("span");
    lineSpan.innerText = routeIds.join("\n");
    lineSpan.classList.add("line-span");
    scheduleDiv.appendChild(lineSpan);

    const dirSpan = document.createElement("span");
    dirSpan.innerText = headsigns.join("\n");
    dirSpan.classList.add("dir-span");
    scheduleDiv.appendChild(dirSpan);

    const timeSpan = document.createElement("span");
    timeSpan.innerText = times.join("\n");
    timeSpan.classList.add("time-span");
    scheduleDiv.appendChild(timeSpan);

    const buttonsDiv = document.createElement("div");
    buttonsDiv.classList.add("buttons-div");
    cardDiv.appendChild(buttonsDiv);

    const deleteButton = document.createElement("button");
    deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
    deleteButton.classList.add("delete-button");
    buttonsDiv.appendChild(deleteButton);

    const dirButton = document.createElement("button");
    dirButton.innerHTML = '<i class="fas fa-retweet"></i>';
    dirButton.classList.add("reverse-button");
    buttonsDiv.appendChild(dirButton);

    stopList.appendChild(cardDiv);
  });
};
document.addEventListener("DOMContentLoaded", getTerminus);

Terminus contains stop names, and directions contains direction codes.

On refresh, it fetches data from API based on stop name and direction, and displays a card with departure time etc. The problem is, on closing and re-opening the page cards are sometimes displayed in a wrong order. I have found out, that as time between closing and opening lengthens, the probability of this occurring gets higher. After simple refresh everything is in correct order.

Does it have something to do with browser cache? Has anyone had similar issue or knows what's going on?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
pakut2
  • 500
  • 5
  • 21
  • I don't see any code that adds anything to localStorage... – Heretic Monkey Feb 23 '21 at 13:22
  • 1
    `terminus.forEach(async ...)` does not guarantee that the inner api calls resolve in the same order. So ultimately the visible order depends on the response time of each api call. – Yoshi Feb 23 '21 at 13:26
  • @Yoshi is there a way to impose order? – pakut2 Feb 23 '21 at 13:30
  • Yes, if you'd [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) `terminus` to individual promises and then use [`await Promise.all(...)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) on that. Though you'd need to move your dom manipulation to the callback of that promise. – Yoshi Feb 23 '21 at 13:33

1 Answers1

0

Alright, as @Yoshi stated, it was insequential promise error. I managed to fix it by using reduce().

Here are the threads that helped me

Resolve promises one after another (i.e. in sequence)?

Why Using reduce() to Sequentially Resolve Promises Works

pakut2
  • 500
  • 5
  • 21