Mark Freid
Mark Freid

Reputation: 49

How do i set a predefined key before local-storage is set?

I have a hotkey which clicks an element on the page and uses the default key 'r'. I also have an input which allows the hotkey to be changed when a key is inputted. When a value is inputted it is cached to local-storage. The only issue is the default key doesn't work with the event, only when the input is set to a value.

let IsInputing = true
let key = 82
 setTimeout(() => {
   key = localStorage.getItem('savedKey');

    input.onchange = function(){
        localStorage.setItem('savedKey', key)
    }

    window.addEventListener("keydown", activate, false);
    function activate(key) {
        if (IsInputing == false) {
            if (key.keyCode == key) {
                console.log('key pressed')
                element.click();
            }
        }
    }
    input.onkeydown = function (key) {
        IsInputing = true
        key = key.keyCode;
        console.log('key changed')
        setTimeout(changeKey, 1000)
    }
    function changeKey() {
        IsInputing = false;
    }
}, 500);

Upvotes: 1

Views: 182

Answers (1)

nem035
nem035

Reputation: 35491

Your problem is that, the first time the code runs, you set key to 82, and then you set it to whatever localStorage.getItem returns, which will return null if nothing is cached (first time).

let key = 82;

setTimeout(() => {
  key = localStorage.getItem('savedKey');
});

This means that your code essentially does:

key = 82;

setTimeout(() => {
  key = null; // <-- you overwrite the key with null on the first run
});

Try setting the default value for key only if localStorage doesn't have a previously cached value:

let DEFAULT_KEY = 82;
setTimeout(() => {
  key = localStorage.getItem('savedKey') || DEFAULT_KEY;
});

Or more tersely:

setTimeout(() => {
  key = localStorage.getItem('savedKey') || 82;
});

Note: to avoid some potential future bugs, you might want to convert your cached value to a number when you return it (localStorage only saves strings).

key = Number(localStorage.getItem('savedKey'));

Or use a string as your default value.

let DEFAULT_KEY = '82';

setTimeout(() => {
  key = localStorage.getItem('savedKey') || DEFAULT_KEY;
});

Having consistent types would avoid errors such as unexpected comparisons:

'82' == 82  // true
'82' === 82 // false


As mentioned in the comments to my answer, you have another bug in the activate function.

You are naming the parameter of activate as key, which will shadow the global key variable when you do the key.keyCode == key comparison.

function activate(key) {
//                ^^^ you are using the same name as the global key
  if (IsInputing == false) {
    if (key.keyCode == key) {
       console.log('key pressed')
       element.click();
    }
  }
}

If key within activate was for example 'abcd', you code will do 'abcd'.keyCode == 'abcd'.

One way to solve it is to rename the activate's parameter:

function activate(activationKey) {
  if (IsInputing == false) {
    if (activationKey.keyCode == key) {
       console.log('key pressed')
       element.click();
    }
  }
}

Upvotes: 1

Related Questions