0

I'm working on a site with multilingual support.

I have a few divs with the same content in multiple languages, and I'm showing the content depending on the language of the users client.

Everything works, but I get an Error which says

Uncaught TypeError: Cannot read property 'style' of null at mywebsite.html

The error points to the case which is displayed.

How can I get rid of the error?

var language = navigator.language || navigator.languages[0];
console.log(language);
var languageFistTwo = language.substr(0,2); // To only keep the first 2 characters.
console.log(languageFistTwo);

switch (languageFistTwo) {
    case "sl":
        document.getElementById("sl").style.display="inline-block";
        break;  
    case "en":
        document.getElementById("en").style.display="inline-block";
        break;
    case "de":
        document.getElementById("de").style.display="inline-block";
        break;
    case "it":
        document.getElementById("it").style.display="inline-block";
        break;
    case "hr":
        document.getElementById("hr").style.display="inline-block";
        break;
    case "ru":
        document.getElementById("ru").style.display="inline-block";
        break;
    default:
        document.getElementById("en").style.display="inline-block";
}
#sl {
    display: none;
}

#en {
    display: none;
}

#de {
    display: none;
}

#it {
    display: none;
}

#hr {
    display: none;
}

#ru {
    display: none;
}
<div id="sl">
Zdravo
</div>

<div id="en">
Hello
</div>

<div id="de">
Gutten Tag
</div>
halfer
  • 19,824
  • 17
  • 99
  • 186
DrDoom
  • 325
  • 1
  • 2
  • 12
  • i didn't add all the languages before... now I did and it doesn't show me the error any more. – DrDoom Jan 16 '20 at 10:36

3 Answers3

1

Uncaught TypeError: Cannot read property 'style' of null at mywebsite.html

One of your document.getElementById statements is returning null. So it cannot read / update the style.

Check that you have all the elements and the IDs are correct.

You can also add the jquery ready function (or equivalent) to ensure that everything is loaded before trying to access the DOM

$( document ).ready(function() {
    console.log( "ready!" );
});

To ensure that you handle errors correctly you should check the element exists before manipulating it

var element = document.getElementById("myElement")
if (element) {
  element.style.display="inline-block";
}
ButchMonkey
  • 1,873
  • 18
  • 30
  • thanks. I'll implement that. I can't use jquery, is there an easy JS alternative to document.ready function? – DrDoom Jan 16 '20 at 10:39
  • A self invoked function at the bottom of your html page should do the job. [More details here](https://stackoverflow.com/a/9899701/6852641) – ButchMonkey Jan 16 '20 at 10:41
  • 1
    While the problem was solved by adding all the Divs, I assume this would be the simplest solution to resolve the problem, so I'm accepting this anwser. Again, I would like to thank everyone for your help. – DrDoom Jan 16 '20 at 11:40
1

Probably, when this code is executed, the DOM is not ready and the element with the id equal to the current language is not defined yet


I would simplify the code by keeping the JS code as simple as possible, making the CSS work for you

var language = navigator.language || navigator.languages[0];
document.documentElement.classList.add(language.substr(0,2));

this will create a class to the root element with the current language

Then the CSS could be

#sl, #en, #de, #it, #hr, #ru {
    display: none;
}

.sl #sl,
.en #en,
.de #de,
.it #it,
.hr #hr,
.ru #ru { display: inline-block; } 

// default value if the language is not available
html:not(.sl):not(.en):not(.de):not(.it):not(.hr):not(.ru) #en {
  display: inline-block; 
}

Doing so, if you need to add another languages you just need to update 2 selectors in the CSS and you don't need to wait for the DOM to be ready (as soon as the element is in the DOM the style will be instantly applied)

Fabrizio Calderan
  • 120,726
  • 26
  • 164
  • 177
  • Thanks. I'll need to decypher the CSS first, but by your description it looks promising. – DrDoom Jan 16 '20 at 10:43
  • Could you help me decypher the JS? so we're adding a `documentElement` to the document, which will be added to root (`html`). To that, we are appending a list of Classes (`classList`), with names obtained by `language.substr(0, 2)`? Is this somewhat correct? So basically the whole html document would have a class "en" – DrDoom Jan 16 '20 at 11:58
  • 1
    document.documentElement is the `html` element. classList is an interface for class manipulation: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList. and yes, The HTML element has a class with the language detected. – Fabrizio Calderan Jan 16 '20 at 12:00
  • already have the link opened. thanks for the document.documentElement. =) – DrDoom Jan 16 '20 at 12:01
  • One last question, after this i think i get it. So `.sl #sl`, `.en #en` etc is only shown if the 1st "argument"/class is true. Correct? – DrDoom Jan 16 '20 at 12:18
  • exactly, @DrDoom – Fabrizio Calderan Jan 16 '20 at 12:33
1

test if your div exist.

var language = navigator.language || navigator.languages[0];
console.log(language);
var languageFistTwo = language.substr(0,2); // To only keep the first 2 characters.
console.log(languageFistTwo);

var langs = ["sl","de","it","hr","fr","ru","en"];
if(langs.includes(languageFistTwo) && document.getElementById(languageFistTwo) != null){
      document.getElementById(languageFistTwo).style.display="inline-block";
}else{
    document.getElementById("en").style.display="inline-block";
}
#sl, #en, #de,  #it, #hr, #ru, #fr {
    display: none;
}
<div id="fr">
Bonjour
</div>

<div id="sl">
Zdravo
</div>

<div id="en">
Hello
</div>

<div id="de">
Gutten Tag
</div>

and so on and so on
Sco
  • 749
  • 1
  • 7
  • 13