busterc / objectql

Pick keys from an object, recursively.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build Status Coverage Status

objectql

npm install objectql --save

why?

Performance. Reducing an API payload, picking only what you actually need means less data sent over the wire and therefore less data to stringify or parse.

usage

objectql(source, query)

source must be an object or an array:

const query = {
  a: true
};

// invalid source values
objectql(null, query); // returns null
objectql(undefined, query); // returns undefined
objectql('', query); // returns ''
objectql(10, query); // returns 10
objectql(true, query); // returns true
objectql(false, query); // returns false
objectql(function noop() {}, query); // returns noop function

// valid source values
objectql({}, query); // returns {}
objectql([], query); // returns []
objectql({ b: 'b', c: 'c' }, query); // returns {}
objectql({ a: 'a', b: 'b' }, query); // returns { a: 'a' }
objectql([{ a: 'a', b: 'b' }, { b: 'b', c: 'c' }], query); // returns [{ a: 'a' }, {}]

query must be an object, and only the keys where the value is true will be used. If an object is used as a key's value it will apply that object as the query param to that part of the source object recursively.

const source = {
  a: 'a',
  b: {
    c: 'c',
    d: 'd'
  }
};

// invalid queries
objectql(source, null); // returns source
objectql(source, undefined); // returns source
objectql(source, ''); // returns source
objectql(source, 10); // returns source
objectql(source, true); // returns source
objectql(source, false); // returns source
objectql(source, function noop() {}); // returns source

// ignored query key values
objectql(source, { a: null }); // returns {}
objectql(source, { a: undefined }); // returns {}
objectql(source, { a: '' }); // returns {}
objectql(source, { a: 10 }); // returns {}
objectql(source, { a: false }); // returns {}
objectql(source, { a: function noop() {} }); // returns {}


// valid query key values
objectql(source, { a: true }); // returns { a: 'a' }
objectql(source, { b: true }); // returns { b: { c: 'c', d: 'd' } }
objectql(source, { a: true, b: { c: true } }); // returns { a: 'a', b: { c: 'c' } }

examples

The query object follows a similar pattern to a 'simple' graphql query, for each key in the query objectql will pick the matching key from the source object when the query value is true.

const source = {
  id: 'abc123',
  name: 'Brian',
  age: 24,
  username: 'bmullan91',
  location: {
    address: 'The Cupboard Under the Stairs',
    city: 'Belfast',
    postCode: 'XYZ 123'
  }
};

const query = {
  id: true,
  username: true,
  location: {
    postCode: true
  }
};

const result = objectql(source, query);

// result will be:

{
  id: 'abc123',
  username: 'bmullan91',
  location: {
    postCode: 'XYZ 123'
  }
}

arrays

If given an array objectql will iterate over each item and apply the query to each item.

const source = [
  {
    a: 'a',
    b: {
      c: [
        {
          d: 'd',
          z: 'meh'
        },
        {
          d: 'd',
          z: 'meh'
        }
      ]
    }
  },
  {
    a: 'a',
    b: {
      c: [
        {
          d: 'd',
          z: 'meh'
        },
        {
          d: 'd',
          z: 'meh'
        }
      ]
    }
  }
];
const query = {
  b: {
    c: {
      d: true
    }
  }
};

const result = objectql(source, query);

// result will be:

[
  {
    b: {
      c: [
        {
          d: 'd'
        },
        {
          d: 'd'
        }
      ]
    }
  },
  {
    b: {
      c: [
        {
          d: 'd'
        },
        {
          d: 'd'
        }
      ]
    }
  }
]

invalid values

If the source object is not an object or an array it will be returned back as the result.

const source = null;
const query = {
  a: {
    b: {
      c: true
    }
  }
};

const result = objectql(source, query);

// result will be:

null

The same is true if the invalid value is deeper in the source object:

const source = {
  a: {
    b: null
  }
};
const query = {
  a: {
    b: {
      c: true
    }
  }
};

const result = objectql(source, query);

// result will be:

{
  a: {
    b: null
  }
}

real life example

This should help visualise the data with useful key names.

const source = {
  id: '123',
  modelName: 'model',
  url: 'url',
  date: 1471865716619,
  random: 'random',
  photos: [
    {
      id: '123',
      abc: 'abc'
    }
  ],
  items: [
    {
      id: '456',
      modelName: 'post',
      url: 'url',
      date: 1471865716619,
      photos: [
        {
          id: '123',
          url: 'url'
        }
      ]
    },
    {
      id: '789',
      modelName: 'post',
      url: 'url',
      date: 1471865716619,
      photos: [
        {
          id: '123',
          url: 'url'
        }
      ]
    }
  ]
};
const query = {
  id: true,
  items: {
    modelName: true,
    url: true,
    photos: {
      url: true
    }
  }
};
const result = objectql(source, query);

// result will be:
{
  id: '123',
  items: [
    {
      modelName: 'post',
      url: 'url',
      photos: [
        {
          url: 'url'
        }
      ]
    },
    {
      modelName: 'post',
      url: 'url',
      photos: [
        {
          url: 'url'
        }
      ]
    }
  ]
};

Still not sure, take a look at the tests for more examples.

About

Pick keys from an object, recursively.


Languages

Language:JavaScript 100.0%