Home > Software engineering >  Cannot set properties of undefined in key-value store
Cannot set properties of undefined in key-value store

Time:11-23

I have this code:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./framework.js"></script>
</head>
<body>
  <p f-text="name"></p>
  <script>
    Framework.store('name', 'Joe');
  </script>
</body>
</html>
document.querySelectorAll('*').forEach((element) => {
  if (element.hasAttribute('f-text')) {
    const textValue = element.getAttribute('f-text');
    
    element.innerHTML = window.fStore[textValue];
  }
});

window.Framework = {
  store: (key, value = '') => {
    if (value === '') {
      return window.fStore[key];
    }

    window.fStore[key] = value;
  }
}

But get this error:

TypeError: Cannot set properties of undefined (setting 'name')
    at Object.store (/framework.js:15:24)
    at /:12:15

I want the page to render 'Joe' by getting the key from f-text, finding the key's value in window.fStore, then setting the element.innerHTML as the value. Framework.store() takes a key and a value, if there is no value it returns the value from the key in window.fStore, if there is then it sets window.fStore[key] to the value.

CodePudding user response:

You need to check whether window.fStore exists first.

window.Framework = {
  store: (key, value = '') => {
    if(!window.fStore) window.fStore = {}
    if (value === '') {
      return window.fStore[key];
    }
    window.fStore[key] = value;
  }
}
Framework.store('name', 'Joe');

document.querySelectorAll('*').forEach((element) => {
  if (element.hasAttribute('f-text')) {
    const textValue = element.getAttribute('f-text');
    element.innerHTML = window.fStore[textValue];
  }
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <p f-text="name"></p>
</body>

</html>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You might also need to wait till the window loads first. Some browsers will give you a headache if you dont

window.addEventListener('load', e=>{
  window.Framework = {
    store: (key, value = '') => {
      if(!window.fStore)
        window.fStore = {};
      if (value === '')
        return window.fStore[key];
      window.fStore[key] = value;
    }
  }
  window.Framework.store('name', 'Joe');

  document.querySelectorAll('*').forEach((element) => {
    if (element.hasAttribute('f-text'))
      element.innerHTML = window.fStore[element.getAttribute('f-text')];
  });
} 
  • Related