DoneDeal
DoneDeal

Reputation: 159

localStorage doesn't store updated value

I'm writing a script that lets a user know how much time he spent on a page before refreshing it. To this purpose, I increment a time counter with a setInterval function, and store the data in the browser thanks to localStorage. Once the page is refreshed, I retrieve the data stored, and display them. Meanwhile, the time counter goes back to 0 and starts incrementing again.

Unfortunately, something is wrong with my script because localStorage doesn't store the updated time value (it's always -1). What's wrong with my script?

//TimeSpent = -1, so setInterval sets it to 0s instead of 1s when the page opens. 
var timeSpent = -1

//Update time every second
var timer = setInterval(()=>{
    timeSpent +=1;
    }, 1000);

//If first visit, ask to refresh. Else, display timeSpent on previous page by retrieving localStorage data.
function start(){
  if (localStorage.timeData){
  var timerJson = localStorage.getItem("timeData");
  var timerParsed = JSON.parse(timerJson);
  console.log(`You spent ${timerParsed.time} seconds on previous page`)
  }
  else{
  console.log("Reload the page and see how much time you spent reading this.")
  }
}

//Trig function when page opens.
window.onload = start();

//Before page reloads, store timeSpent in localStorage as a Json file.
   var timeData = {
   time: timeSpent, 
   }

  function storeData (timeData){
  var timerJson = JSON.stringify(timeData) 
  localStorage.setItem("timeData", timerJson);
  }

window.onbeforeunload = storeData (timeData) 

Thanks!

Upvotes: 0

Views: 2284

Answers (3)

SirPilan
SirPilan

Reputation: 4837

I assume you testing this locally. Since local-storage is stored like a cookie domain based (and you dont have a domain when you test your script locally) the data is simply not saved.

In HTML5, is the localStorage object isolated per page/domain?

Edit: By local i mean a simple Html-File without using a webserver.

Upvotes: 0

felinebaron
felinebaron

Reputation: 11

This code works well for me:

let timeData = {
time: -1
}
timeData.time = setInterval(()=>{
    timeData.time += 1 
    console.log(timeData.time)
  }, 1000);
function start(){
  if (localStorage.timeData){
  var timerJson = localStorage.getItem("timeData");
  var timerParsed = JSON.parse(timerJson);
  console.log(`You spent ${timerParsed.time} seconds on previous page`)
  }
  else{
  console.log("Reload the page and see how much time you spent reading this.")
  }
}
window.onload = start();
window.onbeforeunload = function () {
  var timerJson = JSON.stringify(timeData) 
  localStorage.setItem("timeData", timerJson);
}

Upvotes: 0

Nurbol Alpysbayev
Nurbol Alpysbayev

Reputation: 21851

window.onbeforeunload must have a value of type function but in your code it is undefined. Hence you should change it to this:

window.onbeforeunload = function storeData (){
  var timerJson = JSON.stringify(timeData) 
  localStorage.setItem("timeData", timerJson);
  }

I've also removed the parameter from the function, making it a closure.

UPD. As Jonas Wilms noted, you should do the same wilth onload event and start function.

ALSO. In order to always have the actual (fresh) value of timeSpent, you should do this:

const state = {timeSpent: -1}

And everywhere replace timeSpent with state.timeSpent.

This way the closures will have a link to state object, instead of just taking the initial value of a primitive timeSpent.

Upvotes: 1

Related Questions