loading...
Cover image for Optional Chaining - the null safer in javascript

Optional Chaining - the null safer in javascript

rap0so profile image William Godoy ・2 min read

Optional Chaining - the null safer in javascript

Sup reader!

You have probably heard something about ES2020, yeah, this is the new version of Javascript that comes with a new feature called Optional Chaining!

In Javascript, if you want to guarantee the existence of subprops, you can use two basic ways:

// By return at each verification
if (!data) {
    return
}

if (!data.user) {
    return
}

if (!data.user.name) {
    return
}

console.log('The name is:' + data.user.name)
// The name is Will
// By return at complete verification
if (!data|| !data.user || !data.user.name) {
    return
}

console.log('The name is:' + data.user.name)
// The name is Will

OR

const name = data && data.user && data.user.name

console.log('The name is:' + name)
// The name is Will || The name is undefined

Perhaps the second example may seem clear to you,
but... what if u need to apply a fallback?

const name = data && data.user && data.user.name || 'William Godoy'

console.log('The name is:' + name)
// The name is Will || The name is William Godoy

Okay... good...
enough? of course NOT!

This is where the Optional Chaining comes to save us:

const name = data && data.user && data.user.name
// turns to
const name = data?.user?.name

console.log('The name is:' + name)
// The name is Will || The name is undefined

Amazing uh?

but you may be wondering: "If I want to add a fallback, do I do it the same way?"

there are two answers: Yes and No

let me explain, the previous way WILL work:

const name = data?.user?.name || 'William Godoy'

console.log('The name is:' + name)
// The name is Will || The name is William Godoy

BUT prefer:

const name = data?.user?.name ?? 'William Godoy'

console.log('The name is:' + name)

not just because the EcmaScript documentation suggest this, but for the sake of readability!

Cool so far?

so lets recap?

const data = {
    user: {
        name: 'Will',
        age: 24
    },
    status: 200
}

// Old way

const name = data && data.user && data.user.name || 'William'
// Will

// New way
const name = data?.user?.name || 'William'
// Will

And YES, it can be use to chain functions:

const options = {
    api: {
        getData () {

        },
        // ...
    },
    // ...
}

options?.api?.getData()

And used WITH possible callbacks:

function dbDeleteWithoutWhere(callback) {
    // Do stuffs ...
    if (callback) {
        callback()
    }
}

// OR

function dbDeleteWithoutWhere(callback) {
    // Do stuffs ...
    callback && callback()
}

// New Way

function dbDeleteWithoutWhere(callback) {
    // Do stuffs ...
    callback?.()
}

As u can see above, if there's no callback being invoked this will not produce any errors:

// No errors after being invoked
dbDeleteWithoutWhere(undefined)

// No errors after being invoked
dbDeleteWithoutWhere(function callback() {
    // Do callback stuffs
})

Just like functions, you can try it with arrays:

const numbers = {
    integers: [1, 2, 3, 4, 5],
    floats: [1.1, 2.1, 31.9, 45.2]
}

// Old way
const firstInteger = numbers && numbers.integers && numbers.integers[0]
// 1 || undefined

// New way
const firstInteger = numbers?.integers?.[0]
// 1 || undefined

The optional chaining came to facilitate readability, cleanliness and help us with organization!

Thank you for reading this far!

Cheers

Posted on by:

Discussion

pic
Editor guide