JavaScript

Follow

JavaScript

Follow
Initializing an object property if assigning to it fails

Initializing an object property if assigning to it fails

JavaScript Error Messages in Chrome vs FireFox vs Safari

Anjanesh Lekshminarayanan's photo
Anjanesh Lekshminarayanan
·Apr 22, 2023·

2 min read

If you initialize a variable like let applications = {} and assign a property of applications with an array, like as in applications['foo'].push(1) it'll throw an error because foo is not yet a property of applications.

In Chrome it throws the following error :

caught TypeError: Cannot read properties of undefined (reading 'push')

In Firefox it throws :

Uncaught TypeError: applications.foo is undefined

In Safari it throws :

undefined is not an object (evaluating 'applications[property].push'

But at times we would want to push to an array of a property in applications like applications['foo'].push(5) where we don't know beforehand if applications.foo is defined or not.

In that case, we define it as applications.foo = [].

But, if we don't have a list of properties beforehand to mass assign to applications, if the data is coming from an AJAX request, then we can initialize the property using a try-catch block.

try
{
    applications[property].push(response[i]['version']);
}
catch(e)
{
    if (
        // Chrome
        e.message.includes("Cannot read properties of undefined") ||
        // FireFox
        e.message.includes("applications[property] is undefined") ||
        // Safari
        e.message.includes("undefined is not an object (evaluating 'applications[property].push'")
        )
    {
        applications[property] = [response[i]['version']];
    }
    else
    {
        console.error("error = ", e.message);
    }
}

The catch here is to check for two error messages - one for Chrome and one for Firefox.

UPDATE: A guy who works on the Chromium code-base for his company, The Browser Company (Arc.net) mentioned about using the optional chaining operator (?.)which was introduced in ES2020 - so now the entire try-catch block can be replaced with just this :

applications[property]?.push(response[i]['version']);

Thanks Vivek Galatage.

Here is the full example source: https://gist.github.com/anjanesh/fda4de82fe22f82ba0db5caf08308968

 
Share this