Skip to content

Toggle localstorage item in Svelte

new to Svelte so excuse the little knowledge.

I am attempting to save a localStorage item on:click and toggle it when clicked again. Currently, the item is added to localStorage but on a second click, it is not removed. If you refresh the page and click the item is removed but I would like this not to be necessary.

Onclick event

<button on:click={dyslexiaFriendlyFont} class="primaryBtn" >Dyslexia friendly font</button>

Toggle Handling

  let _ac_dyslexiaFriendlyFontToken = localStorage.getItem(
    '_ac_dyslexiaFriendlyFontToken'
  )

  function dyslexiaFriendlyFont() {
    console.log('clicked')
    if (_ac_dyslexiaFriendlyFontToken == undefined) {
      localStorage.setItem('_ac_dyslexiaFriendlyFontToken', 'true')
      body.classList.add('_ac_dyslexiaFont')
    } else (_ac_dyslexiaFriendlyFontToken == "true") {
      localStorage.removeItem('_ac_dyslexiaFriendlyFontToken')
      body.classList.toggle('_ac_dyslexiaFont')
    }
  }

Could someone please help me here? 🙂

Answer

This line is eveluated once when you open the page

  let _ac_dyslexiaFriendlyFontToken = localStorage.getItem(
    '_ac_dyslexiaFriendlyFontToken'
  )

When you click the first time, you write 'true' to localStorage, but the variable _ac_dyslexiaFriendlyFontToken stays the same and so when you click the second time you’ll land again in if (_ac_dyslexiaFriendlyFontToken == undefined)

_ac_dyslexiaFriendlyFontToken is null, but undefined == null // true since you have only two equal signs ~ it’s possible to simply check if(_ac_dyslexiaFriendlyFontToken) or if(!_ac_dyslexiaFriendlyFontToken) to check if the value is truthy or falsy
https://developer.mozilla.org/en-US/docs/Glossary/Truthy
https://developer.mozilla.org/en-US/docs/Glossary/Falsy

So to switch between the if(){}else{} change _ac_dyslexiaFriendlyFontToken in addition to writing to local storage

Here’s your modified example which also adds the class if the token is set in localStorage on opening the page

<script>
    import {onMount} from 'svelte'

    let _ac_dyslexiaFriendlyFontToken = localStorage.getItem('_ac_dyslexiaFriendlyFontToken') // null or 'true'
    console.log(_ac_dyslexiaFriendlyFontToken)

    let body

    onMount(() => {
        body = document.querySelector('body')
        if (_ac_dyslexiaFriendlyFontToken) body.classList.add('_ac_dyslexiaFont')
    })

    function dyslexiaFriendlyFont() {
        if (_ac_dyslexiaFriendlyFontToken) {
            console.log('remove token')
            _ac_dyslexiaFriendlyFontToken = null
            localStorage.removeItem('_ac_dyslexiaFriendlyFontToken')
            body.classList.remove('_ac_dyslexiaFont')
        } else {
            console.log('add token')
            _ac_dyslexiaFriendlyFontToken = 'true'
            localStorage.setItem('_ac_dyslexiaFriendlyFontToken', 'true')
            body.classList.add('_ac_dyslexiaFont')
        }
    }
</script>

<button on:click={dyslexiaFriendlyFont} class="primaryBtn">Dyslexia friendly font</button>

<style>
    :global(._ac_dyslexiaFont) {
        background: teal;
    }
</style>

(_ac_dyslexiaFriendlyFontToken set as 'true' or null like the values from localStorage. Would also work with booleans true and false Not sure if there’s a convention to follow…)