I have this object called 'ctx.instance' which has the following properties:
firstName: 'Ron',
lastName: 'Santo',
minor: true,
accepted: false,
emailChanged: false,
organizationId: 000000000000000001000001,
isDeleted: false,
userId: 55e17a46e410f9603cea515b
This object was passed into my function. I need to strip off the 'emailChanged' property before saving it to the database. So I did this:
delete ctx.instance.emailChanged;
The delete returns 'true' which means the property doesn't exist.
The following statement after the delete yields false which also means it should be gone:
'emailChanged' in ctx.instance
Yet, if I do a console.log(ctx.instance), the 'emailChanged' property is still there and it gets saved to the database.
If I check the property's properties, it says it is configurable. If I do a console.log(ctx.instance.emailChanged) after the delete statement, it says 'undefined'.
Why is it still there?
I've searched all over the internet, tried tons of different things, and I can't find why this is occurring. This is happening within a Node environment.
UPDATE: The DB is Mongo. I'm using Loopback.js models and framework.
The data variable is the object submitted to the server from the client via a PUT. The data object was originally JSON but Loopback has made it a JavaScript object.
The code is within an operation hook so the save to the DB doesn't live within this function.
The 'delete' statement is the last statement within the function before I pass it back off to the framework.
Here is the minimum code for the hook:
module.exports = function( Member )
{
Member.observe( 'before save', upsertMember );
function upsertMember( ctx, next )
{
// displays 'true'
console.log( ctx.instance.hasOwnProperty( 'emailChanged' ) );
// displays 'false'
console.log( ctx.instance.emailChanged );
var isDeleted = delete ctx.instance.emailChanged;
// displays 'true'
console.log( isDeleted );
// displays 'false'
console.log( 'emailChanged' in ctx.instance );
// displays 'false'
console.log( ctx.instance.hasOwnProperty( 'emailChanged' ) );
// displays 'undefined'
console.log( ctx.instance.emailChanged );
// displays object properties including 'emailChanged'
console.log( ctx.instance );
// pass control back to loopback for upsert
// 'emailChanged' gets into MongoDB record
next();
}
}
If any of you know a JSFiddle type of environment that includes Loopback, I'll throw it in there.
Screenshot of my debugger watch right after the delete statement:
I have this object called 'ctx.instance' which has the following properties:
firstName: 'Ron',
lastName: 'Santo',
minor: true,
accepted: false,
emailChanged: false,
organizationId: 000000000000000001000001,
isDeleted: false,
userId: 55e17a46e410f9603cea515b
This object was passed into my function. I need to strip off the 'emailChanged' property before saving it to the database. So I did this:
delete ctx.instance.emailChanged;
The delete returns 'true' which means the property doesn't exist.
The following statement after the delete yields false which also means it should be gone:
'emailChanged' in ctx.instance
Yet, if I do a console.log(ctx.instance), the 'emailChanged' property is still there and it gets saved to the database.
If I check the property's properties, it says it is configurable. If I do a console.log(ctx.instance.emailChanged) after the delete statement, it says 'undefined'.
Why is it still there?
I've searched all over the internet, tried tons of different things, and I can't find why this is occurring. This is happening within a Node environment.
UPDATE: The DB is Mongo. I'm using Loopback.js models and framework.
The data variable is the object submitted to the server from the client via a PUT. The data object was originally JSON but Loopback has made it a JavaScript object.
The code is within an operation hook so the save to the DB doesn't live within this function.
The 'delete' statement is the last statement within the function before I pass it back off to the framework.
Here is the minimum code for the hook:
module.exports = function( Member )
{
Member.observe( 'before save', upsertMember );
function upsertMember( ctx, next )
{
// displays 'true'
console.log( ctx.instance.hasOwnProperty( 'emailChanged' ) );
// displays 'false'
console.log( ctx.instance.emailChanged );
var isDeleted = delete ctx.instance.emailChanged;
// displays 'true'
console.log( isDeleted );
// displays 'false'
console.log( 'emailChanged' in ctx.instance );
// displays 'false'
console.log( ctx.instance.hasOwnProperty( 'emailChanged' ) );
// displays 'undefined'
console.log( ctx.instance.emailChanged );
// displays object properties including 'emailChanged'
console.log( ctx.instance );
// pass control back to loopback for upsert
// 'emailChanged' gets into MongoDB record
next();
}
}
If any of you know a JSFiddle type of environment that includes Loopback, I'll throw it in there.
Screenshot of my debugger watch right after the delete statement:
Share Improve this question edited Aug 29, 2015 at 12:48 EL MOJO asked Aug 29, 2015 at 9:48 EL MOJOEL MOJO 7931 gold badge9 silver badges22 bronze badges 23- 1 will you also post some code please? How can we help to debug something without actually seeing it? :) – Lelio Faieta Commented Aug 29, 2015 at 9:50
-
1
@ELMOJO: I think what everyone wants is some code snippets. Show us what's going on in the function where the
delete
happens. After you "pass it back off to the framework", what happens? Did you try to set a breakpoint and step into that function? – user2844991 Commented Aug 29, 2015 at 12:15 -
1
@ELMOJO: what is the prototype of
ctx.instance
? – user2844991 Commented Aug 29, 2015 at 12:21 -
1
In the code you just posted, you have the ment
displays object properties including 'emailChanged'
-- what value does it show for it?! – T.J. Crowder Commented Aug 29, 2015 at 12:21 -
2
@ELMOJO: wait? what is
__data
? doesctx.instance.hasOwnProperty('emailChanged')
before delete ? – user2844991 Commented Aug 29, 2015 at 12:39
4 Answers
Reset to default 7According to Loopback Operation Hooks
Removing unneeded properties
To remove unwanted properties (fields) from the context object, use the following:
ctx.instance.unsetAttribute('unwantedField');
This pletely removes the field and prevents inserting spurious data into the database.
Should have done this:
ctx.instance.unsetAttribute('emailChanged');
Could it be due to the PUT verb which is used to replace the whole instance and not only some attributes ?(To change only certain attributes you should use the PATCH verb).
So it might be loopback filling the missing attribute in the model and providing a default boolean value (false) for the "emailChanged" attribute.
I was able to remove the unnecessary property from being saved to dataabse using follwing statement Loopback version 3.
In case of ctx.data
delete ctx.data['propertyToBeRemoved'];
In case of ctx.instance
ctx.instance.unsetAttribute('propertyToBeRemoved')
Hope this works
data.emailChanged = undefined;
data.save(callback);
The questioner wants to delete the property of a model and save it to database. But the property of a model cannot be deleted using delete
.