4

I have an object like below:

var doc = {
  local: {
    username: 'admin',
    status: true,
    password: '$2a$08$81Kq7/59ZASHl5k9n5cNvOUSl/HYgpLKZjs66P/OJV8vw.nHW60Ta',
    lastname: 'admin',
    firstname: 'admin',
    email: 'admin@gmail.com',
    datetime_modified: 'TueAug30201623: 10: 56GMT+0530(IST)',
    datetime_created: 'MonAug29201622: 34: 12GMT+0530(IST)'
  },
  roles: [
    'ADMIN',
    'HR'
  ],
  GridOrder: [
    {
      _id: '57e507fce94094be085425c9',
      domainName: 'items'
    }
  ],
  _id: '57c46b0c12907af910167ff5',
  __v: 9
}

Now I want to remove the property "GridOrder" from "doc". I tried using "delete" like below:

delete doc.GridOrder

and also like below:

delete doc['GridOrder']

But nothing is happening. Also I am not getting any error.

How can I remove "GridOrder" from "doc". Any ideas?

gfullam
  • 11,531
  • 5
  • 50
  • 64
Arun Mohan
  • 898
  • 3
  • 18
  • 37
  • 2
    `delete doc.GridOrder` should work. Also js calls them "objects", not "hashmaps". – georg Sep 23 '16 at 12:25
  • This works as expected when using the above code. Is it possible that a) `GridOrder` is defined using `Object.defineProperty()` or b) `GridOrder` is also a property that exists on the object's prototype chain? In both cases, `delete` will fail. *See: [delete operator - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete) – gfullam Sep 23 '16 at 12:42
  • 1
    @gfullam I think you are right on the issue. It was defined like "a". Is there a suggestion of how to delete it?. Also can you post the above comment as an answer? – Arun Mohan Sep 23 '16 at 12:45
  • @ArunMohan Not knowing how you defined it you could do something like `Object.defineProperty(doc, 'GridOrder', {configurable: true})`, this will enable you to delete it how you were trying to do it. Check [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) for more information – taguenizy Sep 23 '16 at 13:05
  • Best guess based on the object's contents: [Why can't I delete a mongoose model's object properties?](http://stackoverflow.com/questions/23342558/why-cant-i-delete-a-mongoose-models-object-properties) Note that this is not a "pure" object, it's a Mongoose object that has custom getters and setters. – JJJ Sep 23 '16 at 13:10
  • @taguenizy You cannot call `defineProperty` a second time on non-configurable properties (if `configurable` is already `false` as is the default case). In other words, `configurable` cannot be set to `true` except at the time of definition. *See : [Advanced objects in JavaScript](http://bjorn.tipling.com/advanced-objects-in-javascript)* – gfullam Sep 23 '16 at 13:38
  • 1
    @gfullam what I meant is where he calls `defineProperty` he should updated it to that if possible – taguenizy Sep 23 '16 at 14:05

3 Answers3

2

Make Object property configurable

Your minimal example works as expected when using the above code.

Based on your comment, GridOrder is actually being defined with Object.defineProperty(), which by default creates non-configurable (read: non-deletable) properties.

Simply pass configurable: true to Object.defineProperty when defining the property GridOrder.

var doc = {
  local: {
    username: 'admin',
    status: true,
    password: '$2a$08$81Kq7/59ZASHl5k9n5cNvOUSl/HYgpLKZjs66P/OJV8vw.nHW60Ta',
    lastname: 'admin',
    firstname: 'admin',
    email: 'admin@gmail.com',
    datetime_modified: 'TueAug30201623: 10: 56GMT+0530(IST)',
    datetime_created: 'MonAug29201622: 34: 12GMT+0530(IST)'
  },
  roles: [
    'ADMIN',
    'HR'
  ],
  _id: '57c46b0c12907af910167ff5',
  __v: 9
}

// Objects defined this way cannot be deleted unless `configurable` is set to `true`
Object.defineProperty(
  doc,
  'GridOrder',
  {
    configurable: true, // Defaults to `false`
    value: [
      {
        _id: '57e507fce94094be085425c9',
        domainName: 'items'
      }
    ]
  }
);

console.log('doc.GridOrder: ', doc.GridOrder);
console.log('delete doc.GridOrder: ', delete doc.GridOrder);
console.log('doc.GridOrder: ', doc.GridOrder);

Caveat

If configurable is false as is the default case, attempting to call defineProperty a second time will result in a JavaScript error… If configurable is set to true you can modify the property again later.

Advanced objects in JavaScript

If you do not have access to the script that uses defineProperty to create GridOrder, then you will be unable to modify or delete it later.

For example, this will fail:

/*
 * Imagine this is provided by some third-party library that you're unable to edit
 */

var doc = {};

// Objects defined this way cannot be modified or deleted because `configurable` defaults to `false`.
Object.defineProperty(
  doc,
  'GridOrder',
  {
    value: [
      {
        _id: '57e507fce94094be085425c9',
        domainName: 'items'
      }
    ]
  }
);

/*
 * Within your script…
 */

console.log('doc.GridOrder: ', doc.GridOrder);
console.log('delete doc.GridOrder: ', delete doc.GridOrder);
console.log('doc.GridOrder: ', doc.GridOrder);

// …attempts to redefine non-configurable properties will fail
Object.defineProperty(
  doc,
  'GridOrder',
  {
    configurable: true
  }
);

console.log('This will never be seen because an Error has been thrown above.');
gfullam
  • 11,531
  • 5
  • 50
  • 64
0

Confirm you have access to the right object and just use delete

var doc = {
  local: {
    username: 'admin',
    status: true,
    password: '$2a$08$81Kq7/59ZASHl5k9n5cNvOUSl/HYgpLKZjs66P/OJV8vw.nHW60Ta',
    lastname: 'admin',
    firstname: 'admin',
    email: 'admin@gmail.com',
    datetime_modified: 'TueAug30201623: 10: 56GMT+0530(IST)',
    datetime_created: 'MonAug29201622: 34: 12GMT+0530(IST)'
  },
  roles: [
    'ADMIN',
    'HR'
  ],
  GridOrder: [
    {
      _id: '57e507fce94094be085425c9',
      domainName: 'items'
    }
  ],
  _id: '57c46b0c12907af910167ff5',
  __v: 9
}
delete doc.GridOrder;
console.log('doc.GridOrder', doc.GridOrder)
console.log(doc)

EDIT

Based on comments how you defined the property using Object.defineProperty you would need to add {configurable: true} so it's possible to delete as you want.

Object.defineProperty(doc, 'GridOrder', {configurable: true}) would do it

Check reference Object.defineProperty

taguenizy
  • 2,140
  • 1
  • 8
  • 26
0

You should run your code in strict mode, in which case a failed deletion will result in a run-time error, making it easier to discover:

Uncaught TypeError: Cannot delete property 'foo' of #(…)`

That would also allow you to catch it if you really wanted to.

In sloppy mode, the delete operator will return false on failure, so you can check its value to help understand what's happening. According to the MDN docs:

true for all cases except when the property is an own non-configurable property, in which case, false is returned in non-strict mode.

Note that the property merely not being present is not a reason for either returning false, or for failing of course.

One commenter claimed:

is also a property that exists on the object's prototype chain? In both cases, delete will fail.

No, a property being on the prototype will not cause the delete to fail. It will succeed (meaning not throw, and not return false), but do nothing.