exist.js

To make it easier to access nested property

Usage no npm install needed!

<script type="module">
  import existJs from 'https://cdn.skypack.dev/exist.js';
</script>

README

exist.js

npm package NPM downloads Dependency Status

If you are tired of those:

// To get `name`, but you do not know whether `employees` and `employees[0]` exist or not
const name = (company.employees && company.employees[0] && company.employees[0].name);

// To set `name`, but you do not know whether `employees` and `employees[0]` exist or not
if (company.employees && company.employees[0]) {
  company.employees[0].name = 'Benjy';
}

// To call a method of nested `Object`
if (company.employees && company.employees[0] && (typeof company.employees[0].getName === 'function')) {
  var name = company.employees[0].getName();
}

You can try exist.js. Something inspired by the existential operator(?. & ?()) of CoffeeScript, but not the same as it. With exist.js, you can access nested property easily:

// To get `name`, but you do not know whether `employees` and `employees[0]` exist or not
const name = exist.get(company, 'employees[0].name');

// To set `name`, but you do not know whether `employees` and `employees[0]` exist or not
exist.set(company, 'employees[0].name', 'Benjy');

// To call a method of nested `Object`
exist.invoke(company, 'employees[0].getName')();

Performance

Maybe you already know lodash's has and get, but exist.js is faster. You can run npm install && node ./perf.js to prove.

Getting Started

Install exist.js as an npm module and save it to your package.json file as a dependency:

npm install exist.js --save

Once installed, it can now be referenced and used easily:

const exist = require('exist.js');
exist({}, 'name') // => false

API

exist.detect(obj, nestedProp)

(Object, String|Array) -> true | Array

To check whether a nested property exists in Object or not. If the nested property is exist, return true. Otherwise, return the path to the property where the value starts missing.

const company = {
  employees: [
    {
      name: 'Benjy'
    }
  ]
};

exist(company, 'employees[0].name') // => true
exist(company, ['bosses', '0', 'age']) // => ['bosses']

exist.get(obj, nestedProp[, defaultValue])

(Object, String|Array[, anything]) -> undefined | value

To get a nested property. If this property does not exist, return undefined or defaultValue.

const company = {
  employees: [
    {
      name: 'Benjy'
    }
  ]
};

exist.get(company, 'employees[0].name') // => 'Benjy'
exist.get(company, 'employees[0].age') // => undefined
exist.get(company, ['employees', '0', 'age'], 18) // => 18

exist.set(obj, nestedProp, value[, createMissing])

(Object, String|Array, anything[, boolean]) -> boolean

To set a value to nested property. If success, return true. Otherwise, false.

If createMissing is true, exist.set will create plain objects and replace missing parts with them, so the value will be set correctly and return true.

const company = {
  employees: [{}]
};

exist.set(company, 'employees[0].name', 'Benjy') // => true
exist.set(company, ['stockholders', '0', 'name'], 'Benjy') // => false, for `stockholders` does not exist

// After this call, company is `{ ..., stockholders: { 0: { name: 'Benjy' } } }`
exist.set(company, ['stockholders', '0', 'name'], 'Benjy', true)

exist.invoke(obj, nestedMethod)

(Object, String|Array) -> Function

To get a nested method, or return NOOP(function() {}) if this property does not exist.

const company = {
  employees: [
    {
      name: 'Benjy',
      sayHi: function(name) {
        console.log('Nice to meet you, ' + name + '!');
      }
    }
  ]
};

exist.invoke(company, 'employees[0].sayHi')('Bob') // => 'Nice to meet you, Bob!'
exist.invoke(company, ['employees', '0', 'sayHello'])('Bob') // => Nothing will happen

License

MIT