Possible Duplicate:
is object empty?
update: (id, data) ->
toUpdate = @find(id)
if toUpdate isnt {}
console.log "hi mom"
console.log toUpdate
toUpdate.setProperty(key, value) for own key, value of data
return toUpdate
find:(id) ->
result = record for record in @storage when record.id is id
return result or {}
Given the following Mocha tests
describe '#update', ->
it 'should return an updated record from a given id and data when the record exists', ->
boogie = createData()
archive = new Archive("Dog")
dog = archive.create(boogie)
result = archive.update(1, {name:"Chompie", age:1})
result.name.should.eql "Chompie"
result.age.should.eql 1
result.emotion.should.eql dog.emotion
it 'should return an updated record from a given id and data when the record does not exist', ->
boogie = createData()
archive = new Archive("Dog")
dog = archive.create(boogie)
result = archive.update(50, {name:"Chompie", age:1})
result.should.not.exist
The result is
Archive #update should return an updated record from a given id and data when the record exists: hi mom
{ id: 1,
validationStrategies: {},
name: 'Boogie',
age: 2,
emotion: 'happy' }
✓ Archive #update should return an updated record from a given id and data when the record exists: 1ms
Archive #update should return empty when the record does not exist: hi mom
{}
✖ 1 of 13 tests failed:
1) Archive #update should return empty when the record does not exist:
TypeError: Object #<Object> has no method 'setProperty'
…surprising, isnt it?
CoffeeScript’s
is(AKA==) is just JavaScript’s===andisnt(AKA!=) is just JavaScript’s!==. So your condition:will always be true since
toUpdateand the object literal{}will never be the same object.However, if
@findcould return a known “empty” object that was available in a constant, then you could useisnt:and later:
For example, consider this simple code:
That will give you this in your console:
But this:
will say:
Demo: http://jsfiddle.net/ambiguous/7JGdq/
So you need another way to check if
toUpdateisn’t empty. You could count the properties intoUpdate:or you could use the special
EMTPYconstant approach outlined above. There are various other ways to check for an empty object, Ricardo Tomasi has suggested a few:_.isEmptywhich is basically theforloop approach with some special case handling and a short circuit._.valuesso you could look at_(toUpdate).values().length. This callsmapinternally and that will be the nativemapfunction if available.JSON.stringify(toUpdate) is '{}', this seems a bit fragile to me and rather round about.Object.keysinstead of theforloop:Object.keys(toUpdate).length isnt 0.keysisn’t supported everywhere though but it will work with Node, up-to-date non-IE browsers, and IE9+.Object.isEmptyand jQuery has$.isEmptyObject.A short-circuiting
forloop appears to be the quickest way to check emptiness:That assumes that you don’t need
ownto avoid iterating over the wrong things. But given that this is just a test suite and that an emptiness test almost certainly won’t be a bottle neck in your code, I’d go with whichever of Underscore, Sugar, or jQuery you have (if you need portability and have to deal with the usual browser nonsense),Object.keys(x).lengthif you know it will be available, and(k for own k of toUpdate).lengthif you don’t have the libraries and have to deal with browser nonsense and aren’t certain thattoUpdatewill be a simple object.