0

I'm having two pages: my-view1 and my-view2. On my-view1 I have two buttons that add and remove data from LocalStorage. On my-view2 I have two simple div's that READ (display) total value, and total in last 6 months value.

However, on the second page, the value will not update if the page is not refreshed. I want the values from my-view2 to be automatically updated everytime the page is loaded (viewed, even if cached).

Here is a plnkr with my-view2 so you can undestrand what I'm trying to do.

https://plnkr.co/edit/ul4T2mduxjElCN4rUUKd?p=info

How can I do this?

Kuba Šimonovský
  • 2,013
  • 2
  • 17
  • 35
unkn0wnx
  • 137
  • 3
  • 14
  • You can use the websockets for that to update your page (view-2) dynamically when ever the value is changed or you have any backend you can use the eventstream for that purpose. And For current scenario you can simply use setinterval to check every second you localstorage if there is any change reflect the change in you page. – Muhammad Zubair Saleem Oct 20 '17 at 10:22
  • Thanks a lot for your reply! I'm currently building this pages as a PWA. Will websockets work even if offline? Also, using setInterval will let the app sleep? or it will run continuously? – unkn0wnx Oct 20 '17 at 10:28
  • setInterval will work in offline mode and yes you can setup a logic to identify that if app is in sleep mode you can stop the interval check and when awake from sleep mode you can resume. But for websockets you need active internet connection and if you are working on myview-1 and myview-2 side by side you can use post messages to communicate and update the my-view-2. – Muhammad Zubair Saleem Oct 20 '17 at 10:47
  • So my only options remains setInterval? I have no idea about setting up a "logic" to indentify if the app is in sleep mode, as I'm just starting with JS and Polymer, and following the Get Started guide. I was thinking that maybe there is a method to reset the value each time the page is viewed. Or, can I set a button that updates the value when on-clicked? – unkn0wnx Oct 20 '17 at 11:10
  • Yes you can set up a button or even you can setup an event listener lets say [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) which can trigger visible or hidden status and you can use these outputs to take actions that when to stop interval and if you page is again active starts the interval with clearinterval function logic is always what outcome you want from your program. – Muhammad Zubair Saleem Oct 20 '17 at 11:49
  • Thanks a lot for your replies! Your idea about about interval on page active is awesome, but it's a bit too much for my understanding as newbie, so I guess a button would be better for me. I'm reading the docs at your provided link, but it's a bit too hard for me to understand it's use clearly. – unkn0wnx Oct 20 '17 at 11:58
  • var visibilityChange = (function (window){ var inView = false; return function(fn){ window.onfocus = window.onblur = window.onpageshow = window.onpagehide = function(e){ console.log(e); if ({focus:1, pageshow:1}[e.type]){ if (inView) return; fn("visible"); inView = true; } else if (inView) { fn("hidden"); inView = false; } }; }; }(this)); visibilityChange(function (state){ console.log(state); }); You need this piece. – Muhammad Zubair Saleem Oct 20 '17 at 12:01
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157133/discussion-between-muhammad-zubair-saleem-and-unkn0wnx). – Muhammad Zubair Saleem Oct 20 '17 at 12:01

1 Answers1

0

You can listen to the storage event to trigger and update some prop in my-view2 when you update localStorage:

<my-view-2 id="myView2"></my-view-2>
<script>
  window.onstorage = function(e) {
    if (e.key !== 'someKeyYouWant') return;
    document.getElementById('myView2').set('someProp', {
      oldValue: e.oldValue,
      newValue: e.newValue
    });
  };
</script>

EDIT (working plunk): Because of a behavior described here the storage event will not be triggered on the window originating the change, so you have to trigger your own storage event, consider the method below:

saveToLs(e) {
  e.preventDefault();
  const newName = this.get('dogName');
  const ls = window.localStorage;
  const synthEvent = new StorageEvent('storage');
  const eventConfig = [
    'storage', 
    true, 
    true, 
    'myDog', 
    ls.getItem('myDog'), 
    newName
  ];

  synthEvent.initStorageEvent(...eventConfig);

  setTimeout((() => { // ensure async queue
    ls.setItem('myDog', newName);
    this.dispatchEvent(synthEvent);
  }).bind(this), 0);
}

...and on the listening side:

handleStorageUpdate(e) {
  if (e.key !== 'myDog' || e.newValue === this.get('dogName')) return; 
  this.set('dogName', e.newValue);
}

Please note the if conditional handling potential duplicate updates with the same value.

Here is a working plunk for you to play with

  • Hi there! Thanks for your reply. I've added the code to `my-view2` page, but I still cannot make it work. I even tried to replace "value replacement" to console.log to see if it reads LocalStorage, but it won't. I'm pretty sure I'm doing something bad in the code, but just cannot understand where. I made a plnkr: https://plnkr.co/edit/HCIw7ExZ2rg7XEjQMLZi?p=catalogue – unkn0wnx Oct 22 '17 at 09:20
  • The solution will not work on its own due to the behavior described here https://stackoverflow.com/a/4679754/2533680, I will update my answer with a working example. – Eduardo M - bbaaxx Oct 25 '17 at 06:02
  • so there is no way for me to do that? – unkn0wnx Oct 26 '17 at 10:25
  • Check the working plunker, there is a way you can do it but it requires you to make your own event. – Eduardo M - bbaaxx Oct 26 '17 at 15:21