0.5.0 • Published 8 years ago

mappersmith-object v0.5.0

Weekly downloads
1
License
MIT
Repository
github
Last release
8 years ago

npm version Build Status

Mappersmith Object

This project is inspired by the Ember.Object project, it aims to provide a light layer on top of your objects/responses to help with common annoyances which the javascript world provides daily. It helps you with a common interface to access attributes and really useful helpers to deal with daily problems.

This project carries the name mappersmith- because it was planned to deeply integrate with Mappersmith project, but this is no longer true, this project doesn't require Mappersmith anymore and can be used standalone.

Browser support

This project was designed considering modern browsers. However, all the methods used are from ES5 and can be included by polyfills.

Install

NPM

npm install mappersmith-object

Browser

Download the tag/latest version from the build folder

Build from the source

npm install
npm run release

Features

Assuming the following data:

var data = {
  name: "Someone",
  age: 27,
  human: true,
  clicks: 3,
  company: {
    name: "SomethingCool.io",
    sectors: ["1A", "2B", "9Z"],
    floors: {
      first: "A",
      second: "B"
    }
  }
}

and the following require:

var MappersmithObject = require('mappersmith-object');

Table of Contents:

Constructors:

Object methods:

Constructors

create

This method is used to wrap your objects. With strict: true operations with undefined attributes will raise an exception.

var obj = MappersmithObject.create(data);
// or
var obj = MappersmithObject.create(data, {strict: true});

extend

This method is a constructor function for "models". It takes a model definition and returns a constructor function based on create.

var Person = MappersmithObject.extend({
  profile: function() {
    return this.get('name') + ', age: ' + this.get('age');
  }
});

var obj = new Person(data);
obj.get('name') // Someone
obj.profile() // Someone, age: 27

Object methods

attributes

Returns a plain javascript object with your attributes.

obj.attributes() // {name: 'Someone', ...}

It accepts a list of keys to filter the result.

obj.attributes('name') // {name: 'Someone'}
obj.attributes('name', 'human') // {name: 'Someone', human: true}

obj.attributes('wrong.key', 'company.name')
// {wrong: {key: null}, company: {name: 'SomethingCool.io'}}

It will raise exception for invalid keys in strict mode.

get

Retrieves the value of a property from the object. It accepts chain calls. It works with array indexes.

obj.get('name') // 'Someone'
obj.get('company.name') // SomethingCool.io
obj.get('company.name.0') // S
obj.get('company.floors.first') // A
obj.get('company.sectors.0') // 1A
obj.get('company.sectors.1') // 2B
obj.get('company.sectors.-1') // 9Z - the last item
obj.get('company.sectors.99') // null
obj.get('wrong') // null
obj.get('wrong.chain') // null

It's possible to assign a default value.

obj.get('wrong', {default: 'My Name'}) // 'My Name'

It will raise exception for invalid keys in strict mode.

obj.get('invalid')
// throws MappersmithObject.Exceptions.StrictViolationException

set

Sets the provided value to the key, creating inexistent nodes in the process.

obj.set('name', 'Other') // 'Other'
obj.set('company.name', 'Name') // 'Name'
obj.attributes() // {name: 'Other', company: {name: 'Name', ...}, ...}

With inexistent keys/chains:

obj.set('some.new.key.chain', true) // true
obj.get('some.new.key') // {chain: true}
obj.get('some.new.key.chain') // true

If the value assigned is a promise it will be resolved and the value set. A promise will be returned instead of the value.

obj.set('company.name', promiseObj) // Promise (will resolve and set)
obj.set('company.name', promiseObj).then(function(value) {
  console.log(value) // value => promise value

  obj.get('company.name')
  // return == value (the promise is resolved and the value assigned)
})

It will raise exception for invalid keys in strict mode.

obj.set('invalid', 'value')
// throws MappersmithObject.Exceptions.StrictViolationException

fetch

Fetches data from the object, using the given key. If there is data in the object with the given key, then that data is returned. If there is no such data in the object, then the second argument value will be set and returned.

The second argument can be a value or a function. The function will be executed to generate the value.

obj.fetch('name', 'Default Name') // 'Someone'
obj.fetch('wrong', 'Default value') // 'Default value'
obj.fetch('wrong', function() { return 'Default Value'}) // 'Default value'

It will raise exception for invalid keys in strict mode.

obj.fetch('invalid', 'value')
// throws MappersmithObject.Exceptions.StrictViolationException

alias

Create alias accessors to your attributes. Returns this so it can be chained with other methods.

obj.alias({fullName: 'name'}) // argument: object with {aliasName: 'attributeToBeAliased'}
obj.get('fullName') // 'Someone'
obj.set('fullName', 'New Name')
// obj.get('fullName') => 'New Name'
// obj.get('name') => 'New Name'

It also works with chains:

obj.alias({floors: 'company.floors'})
obj.get('floors') // {first: "A", second: "B"}

When called without arguments returns the alias mapping:

obj.alias() // {fullName: 'name'}

Aliased values can only be returned by attributes when explicit requested, example:

obj.alias({fullName: 'name'})
obj.attributes() // Object without alias: {name: 'Someone', ...}
obj.attributes('fullName', 'age') // {fullName: 'Someone', age: 27}

has

It checks if a property exists. It won't raise any exception for invalid keys, even in strict mode.

obj.has('name') // true
obj.has('company.floors') // true
obj.has('invalid') // false
obj.has('company.invalid.chain') // false

with {strict: true}:

obj.has('invalid') // false (no exception in this case)

Also aliased as: is

obj.is('human') // true
obj.is('enabled') // false

inc

Set the value of a property to the current value plus some amount. The default amount is 1. If the value is not a number false will be returned instead. Undefined keys will be initialized with 1.

obj.inc('clicks') // 4
obj.inc('clicks', 2) // 6
obj.inc('invalid') // 1
obj.inc('name') // false

It will raise exception for invalid keys in strict mode.

dec

Set the value of a property to the current value minus some amount. The default amount is 1. If the value is not a number false will be returned instead. Undefined keys will be initialized with -1.

obj.dec('clicks') // 5
obj.dec('clicks', 3) // 2
obj.dec('invalid') // -1
obj.dec('name') // false

It will raise exception for invalid keys in strict mode.

toggle

obj.toggle('human') // false
obj.toggle('human') // true
obj.toggle('invalid') // true
obj.toggle('name') // false
obj.toggle('name') // false

isBlank

A value is blank if it's false, null, undefined, empty, NaN or a whitespace string. For example, '', ' ', null, undefined, [], and {} are all blank.

obj.isBlank('invalid') // true

// imagine {test1: '', test2: ' a ', test3: {}}
obj.isBlank('invalid') // true
obj.isBlank('test1') // true
obj.isBlank('test2') // false
obj.isBlank('test3') // true

It will return true for invalid keys in strict mode.

isPresent

A value is present if it's not blank.

obj.isPresent('name') // true
obj.isPresent('invalid') // false

It will return false for invalid keys in strict mode.

toArray

Converts the value to an array. If the value is already an array, the same value will be returned. For undefined or null values a blank array ([]) will be returned.

obj.toArray('name') // ['Someone']
obj.toArray('age') // [27]
obj.toArray('invalid') // []
obj.toArray('company.sectors') // ["1A", "2B"]

If called without arguments it will return the object attributes wrapped.

obj.toArray() // [{name: "Someone", ...}]

It will raise exception for invalid keys in strict mode.

reset

Resets the attributes to the original value.

obj.attributes() // {name: 'Someone', ...}
obj.set('name', 'Thor') // 'Thor'
obj.attributes() // {name: 'Thor', ...}

obj.reset() // {name: 'Someone', ...}
obj.attributes() // {name: 'Someone', ...}

update

Deeply update the attributes.

obj.update({name: 'New', human: false}) // {name: 'New', human: false, ...}
obj.get('name') // 'New'
obj.attributes() // {name: 'New', human: false, ...}

extend

Merges the content into the object. This method provides a way to enhance the object with mixins/modules. extend can be called several times, the methods can be overridden within the next calls.

obj.extend({
  greetings: function() {
    return 'Hello ' + this.get('name');
  },
  sectorCountPlus: function(factor) {
    return this.get('company.sectors') + factor;
  }
}) // will return (this) obj

obj.greetings() // 'Hello Someone'
obj.sectorCountPlus(3) // 2 + 3 = 5

It's possible to call extend several times.

var LogMixin = {
  info: function() {
    console.log.apply(this, arguments);
  }
}

var ToJsonMixin = {
  toJsonString: function() {
    return JSON.stringify(this.attributes());
  }
}

obj.extend(LogMixin).extend(ToJsonMixin);

obj.info('message');
obj.toJsonString();

Tests

npm test

Compile and release

Compile: npm run build

Release (minified version): npm run release

License

See LICENSE for more details.

0.5.0

8 years ago

0.4.0

8 years ago

0.3.0

8 years ago

0.2.0

8 years ago

0.1.1

9 years ago

0.1.0

9 years ago