localStorage not working

Question:
My HTML Repl uses the localStorage API, and it doesn’t seem to be working. It returns an error saying:

TypeError: Cannot read properties of undefined (reading 'encounters')
https://....replit.dev/script.js:163

What is wrong with my code and why is localStorage not working?
Repl link:
https://replit.com/@element1010/Cosmic-Adventure#script.js

function generateSaveCode() {
  let save = `${money};${s.tier};${s.space[0]};${s.space[1]};${JSON.stringify(s.rooms)};${JSON.stringify(s.accessories)};${s.astronauts};${s.currentPlanet};${technologiesResearched};${planetSaves}`;
  localStorage.setItem("save", save);
}

function loadSaveCode() {
  let save = localStorage.getItem("save").split(";");
  money = parseInt(save[0]) ?? 7500;
  s.tier = parseInt(save[1]) ?? 0;
  s.space = [parseInt(save[2]), parseInt(save[3])] ?? [0, 0];
  s.rooms = JSON.parse(save[4]) ?? [];
  s.accessories = JSON.parse(save[5]) ?? [];
  s.astronauts = parseInt(save[6]) ?? 0;
  s.currentPlanet = save[7] ?? "earth";
  technologiesResearched = save[8] ?? [];
  for(let i = 0; i < technologiesResearched.length; i++) {
    technologies[technologiesResearched[i]].researched = true;
  }
  planetSaves = save[9] ?? [
    ["earth", 1, false, true],
    ["moon", 0, false, false]
  ];
  for(let j = 0; j < planetSaves.length; j++) {
    planets[planetSaves[j][0]].encounters[0] = planetSaves[j][1];
    planets[planetSaves[j][0]].scouted = planetSaves[j][2];
    planets[planetSaves[j][0]].visited = planetSaves[j][3];
  }
}

I went to your replit and looked at the line number referenced (136). It appears you have changed the code meaning I can’t find the line of code to backtrack to find the eventual error.

1 Like

Yes, sorry, it is actually line 136. @PhoenixStarlight

Btw, using type coercion is faster than parseInt.

{String with Number} - 0 will convert a string into a number

Ok, is that the problem with localStorage or is the problem something else?

Ok so I realized I’ve committed some debugging errors. (Misreading line numbers)

Just a note that because your function was defined before some variables exist, your function may unexpectedly pick the wrong variables.

But the problem is that planetSavesis not properly handled, and as such is just the string literal after you have split up the string.
"earth,1,false,true,moon,0,false,false"

I did a little bit of debugging, and the code that I have now is this:

function generateSaveCode() {
  let save = `${money};${s.tier};${s.space[0]};${s.space[1]};${JSON.stringify(s.rooms)};${JSON.stringify(s.accessories)};${s.astronauts};${s.currentPlanet};${JSON.stringify(technologiesResearched)};${JSON.stringify(planetSaves)}`;
  localStorage.setItem("save", save);
}

function loadSaveCode() {
  let save = localStorage.getItem("save").split(";");
  money = parseInt(save[0]) ?? 7500;
  s.tier = parseInt(save[1]) ?? 0;
  s.space = [parseInt(save[2]), parseInt(save[3])] ?? [0, 0];
  s.rooms = JSON.parse(save[4]) ?? [];
  s.accessories = JSON.parse(save[5]) ?? [];
  s.astronauts = parseInt(save[6]) ?? 0;
  s.currentPlanet = save[7] ?? "earth";
  technologiesResearched = save[8] ?? [];
  for(let i = 0; i < technologiesResearched.length; i++) {
    technologies[technologiesResearched[i]].researched = true;
  }
  planetSaves = JSON.parse(save[9]) ?? [
    ["earth", 1, false, true],
    ["moon", 0, false, false]
  ];
  for(let j = 0; j < planetSaves.length; j++) {
    planets[planetSaves[j][0]].encounters[0] = planetSaves[j][1];
    planets[planetSaves[j][0]].scouted = planetSaves[j][2];
    planets[planetSaves[j][0]].visited = planetSaves[j][3];
  }
}

And the problem now is this:

TypeError: Cannot set properties of undefined (setting 'researched')
  at loadSaveCode (https://31a77101-95ef-4cec-9950-9d9b477fb1c1-0011qhlkew33wu5.picard.replit.dev/script.js:133:56)
  at https://31a77101-95ef-4cec-9950-9d9b477fb1c1-0011qhlkew33wu5.picard.replit.dev/script.js:386:1

You basically need to parse everything since your string is a collection of JSON objects, delimited by ;.
E.x {"somekey":1, "A": "b"};{};

I suggest just creating a state object and storing that as the JSON to avoid having to split by delimiters, remember to parse (or not)