Search code examples
node.jsundefinedtypeof

Cannot read property of undefined while checking for undefined


I'm having some issues managing 'undefined' in Node v10

Considering the following object:

const dictionary = {
    weeklyContest: {
        victorySubject: {
            en: 'Congratulations, you are this week\'s lucky winner!',
            fr: 'Félicitations, vous êtes l\'heureux gagnant de cette semaine!',
            de: 'Herzlichen Glückwunsch, Sie sind der glückliche Gewinner dieser Woche!',
            es: '¡Felicidades, eres el afortunado ganador de esta semana!',
            ru: 'Поздравляем, вы счастливый обладатель этой недели!',
            default: 'Congratulations, you are this week\'s lucky winner!'
        }
    },
    default: {
        victorySubject: {
            en: 'Congratulations, you are today\'s lucky winner!',
            default: 'Congratulations, you are today\'s lucky winner!'
        }
    }
};

and the following piece of code:

let contestSlug = 'nonExistingContest';
let stringName = 'victorySubject';
let stringLocale = 'fr';
let contestProp = (typeof(dictionary[contestSlug]) === 'undefined' || typeof(dictionary[contestSlug][stringName]) === 'undefined') ? 'default' : contestSlug;
let localeProp = (typeof(dictionary[contestProp][stringName][stringLocale]) === 'undefined') ? 'default' : stringLocale;

contestProp gets correctly assigned with 'default' cause there is no first-level property called 'nonExistingContest', making the second type check on line 5 become:

let localeProp = (typeof(dictionary['default']['victorySubject']['fr']) === 'undefined') ? 'default' : stringLocale;

Now, considering I had a debug console attached and considering this debug result:

contestProp
> 'default'

stringName
> 'victorySubject'

stringLocale
> 'fr'

typeof(dictionary[contestProp][stringName][stringLocale]) === 'undefined'
> true

typeof(dictionary['default']['victorySubject']['fr']) === 'undefined'
> true

I don't understand why the assignment for localeProp on line 5 returns the error:

Cannot read property 'victorySubject' of undefined

Despite I actually just want to check for undefined. I already checked similar questions and they all suggest alternative implementations, but I would really like to understand the behaviour that leads to the error. Any ideas? Thanks in advance for your time!


Solution

  • I solved the issue by creating a middle variable each time with the partial object I need to compare:

    OLD

    let contestProp = (typeof(dictionary[contestSlug]) === 'undefined' || typeof(dictionary[contestSlug][stringName]) === 'undefined') ? 'default' : contestSlug;
    let localeProp = (typeof(contestStrings) === 'undefined' || typeof(contestStrings[stringLocale]) === 'undefined') ? 'default' : stringLocale;
    

    NEW

    let contestProp = (typeof(dictionary[contestSlug]) === 'undefined') ? 'default' : contestSlug;
    let partialDictionary = dictionary[contestProp];
    contestProp = (typeof(partialDictionary[stringName]) === 'undefined') ? 'default' : contestSlug;
    partialDictionary = dictionary[contestProp][stringName];
    let localeProp = (typeof(partialDictionary) === 'undefined' || typeof(partialDictionary[stringLocale]) === 'undefined') ? 'default' : stringLocale;
    

    I still I don't follow the logic leading to the error. I will wait a bit for some ideas before accepting this answer.