get or prop

The safe way is to create a get function. For objects you know the shape of, meaning you know what properties and value types they typically have, you can create these yourself.

const getFirstName = person => {
    if(person) {
        return person.firstName
    }
    return undefined
}

Then you can test it to verify it's safe:

expect(getFirstName(person)).to.equal('Jesse')
expect(getFirstName(undefined)).to.equal(undefined)

This is such a common thing to do that Lodash has a get function, Ramda and Sanctuary have prop.

import { get } from 'lodash'

console.log(get(person, 'firstName')) // Jesse
console.log(get(person, 'fistName')) // undefined
console.log(get(undefined, 'firstName')) // undefined

Dem Deep Gets

Deeply nested properties, however, require null or null operators:

const getStreetAddress = person => {
    if(person && person.address && person.address.home) {
        return person.address.home.street
    }
    return undefined
}

It's less code and safer just to use get with the path:

const getStreetAddress = person => get(person, 'person.address.home.street')

Now those are just Objects. Arrays require you to do runtime type checking:

const getFirstHomePhone = person => {
    if(
        person 
        && person.address 
        && person.address.home 
        && Array.isArray(person.address.home.phone)
        ) {
        return person.address.home.phone[0]
    }
    return undefined
}

... or you could just use get:

const getFirstHomePhone = person => get(person, 'person.address.home.phone[0]')

This also works great for deeply nested JSON data structures you often get back from REST API's as well as SOAP and XML you've parsed to JSON.

Default Values

You'll often configure your Node API using the config library. One thing you'll run into when configuring for different development environments like dev, qa, and prod is default values in case the configuration intentionally doesn't exist. In the browser, if you run into configuration erorrs, you just fall back to the defaults so the application still works.

You can do that using get or Ramda's propOr:

const url = get(configuration, 'services.emailURL', 'http://dev.server.com/email')

If it can't find the services.emailURL path on configuration, or if configuration is undefined, it'll just default to that dev url, 'http://dev.server.com/email'.

results matching ""

    No results matching ""