Obj.observe("before save", async function (ctx,next) {
// getting entire instance is possible, yes
const oldData = ctx.currentInstance.__data;
const changedData = ctx.data;
// I have changed only one attribute/field(this can be any field at runtime) and I want to detect that change in the entire instance.
// is there any way?
return next();
}
https://github.com/strongloop/loopback/issues/2144
This does not solve the issue as I have to send the entire instance rather sending just one changed attribute which is suggested in this question as an answer.
@hacksparrow @bajtos , could you please help with this question? Thanks.
@bajtos do we have ctx.currentInstance property?
@hacksparrow yes. See at https://loopback.io/doc/en/lb2/Operation-hooks.html#currentinstance. But what is @nancycg trying to achieve? Pardon me but I don't understand the question.
Thanks @sujeshthekkepatt.
ctx.currentInstance is from LoopBack 2, which reached end of life in April. We are not supporting 2.0 anymore.
@nancycg The title "How to get affected attributes of persisted model" and your requirement "I have to send the entire instance rather sending just one changed attribute" seem to be talking about different things.
Can you be more specific and clearer?
@hacksparrow Yes. It's from LB2. I thought this may be @nancycg referring.
Thanks for the replies. Let me explain once again ...
I am using "before save" hook of loopback.
Let's say oldObject = data before update.
and updatedObject = data after the update.
Based on who is calling the hook function I am receiving
either
ctx.currentInstance(This is oldObject mean data without changes) + ctx.data(this is updatedObject)
or
ctx.instance (This is new data)
case-1
If the object is new than no comparison can be done.
if(ctx.instance){//true}
case-2
If the object is updated then we can compare data and find the changes that which property is changed.
if(ctx.currentInstance && ctx.data){//true}
Now my query is related to case-2.
If I want to find the diff between oldObject and updatedObject then I can use lodash or I can use deep-diff (deep-diff is a javascript/node.js module providing utility functions for determining the structural differences between objects and includes some utilities for applying differences across objects.)
Both external solutions.
Is there any other clean way of finding diff between the objects.
And how to get affected attributes/properties of the persisted model? The condition is that entire object is received in ctx.currentInstance and ctx.data.
I hope I am clear in my question this time. I am using node v10.0.0
I don't think there is a built-in mechanism in loopback. I think you may have to stick with your current solution. Based on this https://loopback.io/doc/en/lb3/Operation-hooks.html before hooks trigger whenever an update occurs or create occur. When upsert happens you can get the attributes from ctx.data property that are going to change. I think your solution is more appropriate. What do you think @hacksparrow
Actually, My solution is incomplete and looking for a more precise solution. I don't get the oldObject (= data before the update ) all the time as sometimes based on calling API, I am getting ctx.instance + isNewInatance= false. In this case, I am not getting any oldObject to compare with but isNewInatance == false shows that something is updated. ctx.instance having the updated object and without old object, I can not compare and find the changes.
Regardless of what is calling I need to save the oldObject with me and on 'before save' hook That oldObject need to be there to compare with the updated object so that I can get a diff. Please suggest on it. What might be the best solution for it? without changing existing code much.
Using LB3
@hacksparrow @sujeshthekkepatt
@bajtos we don't have ctx.currentInstance property all the time.
@nancycg Okay so you want to take diff between old data and the new data, right? If that what you want I think you can't achieve it with operation hooks. I think you have to introduce much naive approach like assign old data to some variable, update the instance and diff the old variable with the new instance something like that.
oldInstance = before_update();
newInstance = after_update();
diff(oldInstance,newInstance);
If there are any other options @hacksparrow @bajtos ?
trying to do it with mixins https://github.com/fullcube/loopback-ds-changed-mixin
Hope someone suggests a better and clean solution. @hacksparrow @bajtos
LoopBack does not offer any built-in tools for comparing old & new instance data to find exactly which properties were changed.
When the context contains ctx.instance (and there is no ctx.currentInstance), then it's because LoopBack does not have the old data. You can fetch the old data from the database via ctx.Model.findById(). This is roughly the same way as ctx.currentInstance is filled. Just be aware that this is introducing a race condition, some other code (or REST API client) can modify the data after you loaded the current instance but before you make your updates.
Most helpful comment
@bajtos do we have
ctx.currentInstanceproperty?