0

I’m checking if a property 'lessons' (not inherited) is not present in obj, All these give me true

(typeof obj['lessons'] == undefined)

(!(obj.hasOwnProperty('lessons')))

(!(hasOwnProperty.call(obj,'lessons')))

(!(_.has(obj, 'lessons')))

(!Object.prototype.hasOwnProperty.call(obj, 'lessons’))

but the property is present in the object, when i print keys by using (key in obj). I don't want to use it as it's very slow and my object is huge.

I found this on stackoverflow, but I don't understand what it's trying to do or how to use it with node.js.

I'd also like to know how are the mentioned ways of using hasOwnProperty are different.

EDIT adding code

My code is:

console.log("LS:",JSON.stringify(obj)) ;
if (typeof obj['lessons'] == undefined)
    console.log('typeof undefined');
else {console.log('typeof not undefined');}

if (!(obj.hasOwnProperty('lessons')))
    console.log('hasOwnProperty: false');
else {console.log('hasOwnProperty not undefined');}

if (!(hasOwnProperty.call(obj,'lessons')))
    console.log('hasOwnProperty.call');
else {console.log('hasOwnProperty.call not undefined');}

if (!(_.has(obj, 'lessons')))
    console.log('_.hash');
else {console.log('_has not undefined');}

if (!(_.has(obj, 'lessons')))
    {obj['lessons'] = {"levels": []};}
else
    {console.log("has lesson level ");}

console.log("Lesson ", JSON.stringify(obj.lessons));

And the output I'm getting is:

LS: {"_id":"N9zmznzAWx","time":"1970-01-01T00:33:36.000Z","lessons":{"levels":["abc"]}}
typeof not undefined
hasOwnProperty: false
hasOwnProperty.call
_.hash
Lesson {"levels":[]}

Same case with all others..

SOLUTION It works when I use JSON.parse(JSON.stringify(obj)) instead of obj.

Community
  • 1
  • 1
Shipra
  • 1,259
  • 2
  • 14
  • 26
  • try to check with dot operator (obj.lessons) – shreyansh Apr 01 '16 at 03:25
  • 1
    Have you tried simply `if ( ! ('lessons' in obj)) { ... }` – jperezov Apr 01 '16 at 03:27
  • 2
    `(key in obj)` *does* take into account inherited properties. If the `in` operator is what you are looking for, then you should use it. – Bergi Apr 01 '16 at 03:29
  • 2
    Please show us how you did construct your `obj`, so that we can tell what properties it really has (where, and with what attributes). – Bergi Apr 01 '16 at 03:30
  • it works perfectly as expected [fiddle](https://jsfiddle.net/mnjztc86/) it doesnt log response. can you replicate a your issue in fiddle ? – Jairo Malanay Apr 01 '16 at 03:30
  • Uh, the output of `JSON.stringify` says *nothing* about what your object really is. Please show us where you got it from, and how it was constructed. – Bergi Apr 01 '16 at 04:04
  • @Bergi I used the wrong case, updated the question. I am getting the object from mongoDB using mongoose and editing it. – Shipra Apr 01 '16 at 04:05
  • @Shipra: Well *that* is significant information. You might have better luck trying your tests against `obj.toJSON()` instead of `obj` itself. – Bergi Apr 01 '16 at 04:09
  • 1
    Don't use `hasOwnProperty.call`. Maybe `Object.prototype.hasOwnProperty.call` or `({}).hasOwnProperty.call`. But the [[Prototype]] internal slot of the global object is implementation dependent, so better don't assume it inherits from `Object.prototype`. – Oriol Apr 01 '16 at 04:13
  • @Bergi I'm getting _TypeError: Object # has no method 'toJSON'_ – Shipra Apr 01 '16 at 04:15

3 Answers3

1

Your checks aren't working because Mongoose document objects don't use simple object properties to expose their fields.

Instead, you can use the Document#get method to do this (with your obj renamed to doc):

var isMissing = (doc.get('lessons') === undefined);

Or you can create a plain JS object from your document by calling toObject() on it, and then use hasOwnProperty on that:

var obj = doc.toObject();
var isMissing = !obj.hasOwnProperty('lessons');
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
0

Here is a function that I wrote as an example to test three ways you have listed in your question:

function check(obj) {
  if (!obj.hasOwnProperty("lessons")) {
    console.log('nope');
  }  
  if (!_.has(obj, 'lessons')) {
    console.log('nope');
  }  
  if (!obj.lessons) {
    console.log('nope');
  }
}

Here is JSBIN that runs the function on two objects, one with 'lessons' and one without:

Example JsBIN

omarjmh
  • 13,632
  • 6
  • 34
  • 42
0

typeof returns a string

var obj = {};
console.log(typeof (typeof obj.lessons));

https://jsfiddle.net/0ar2ku7v/

So you must compare it as such:

if (typeof obj.lessons === 'undefined')
  console.log('nope');
King Friday
  • 25,132
  • 12
  • 90
  • 84