When working with an instance of a record in Gadget (either results returned from the client package or the context.record in your code effects), you are working with a GadgetRecord. GadgetRecord is a wrapper class around the properties of your object that provides additional helper functionality such as change tracking.
GadgetRecord properties
Every GadgetRecord shares a common set of Gadget system properties such as id, updatedAt, createdAt, and state. In addition to these Gadget system properties, any model fields you've added to your model will also be included in the GadgetRecord. These properties can be get and set via their apiIdentifier.
JavaScript
1const user =await api.user.findOne("123");
2
3// Gadget system properties
4console.log(user.id);// "1"
5console.log(user.state);// "created"
6console.log(user.createdAt);// Tue Jun 15 2021 10:30:59 GMT-0400
7console.log(user.updatedAt);// Tue Jun 15 2021 12:18:01 GMT-0400
GadgetRecord instances track changes made to their local state, and provide a change tracking API for determining what properties have changed (locally) on a record.
You can use this change tracking in your own applications via the client package in the following manner:
By working with this single GadgetRecord instance user in your frontend, you could use the change tracking API to determine if there is anything that needs to be persisted via one of your actions.
Additionally, you are also working with GadgetRecord instances when using the context.record in your run effects, conditions, and validations.
If you wanted to determine whether or not a change was made to the record in a run effect of an update action, you could do the following:
Return a JSON representation of the keys (by apiIdentifier) and values of your record.
JavaScript
1const record =newGadgetRecord({
2title:"A title",
3tags:["Cool","New","Stuff"],
4price:123.45,
5});
6console.log(record.toJSON());
7//{
8// "title": "A title",
9// "tags": ["Cool", "New", "Stuff"],
10// "price": 123.45
11//}
Get and set properties that share the same name as GadgetRecord functions
If the apiIdentifier of your model field has the same name as one of the GadgetRecord functions described above, you will need to work with it via the getField and setField functions.
JavaScript
1const record =newGadgetRecord({title:"Something",changed:true});
2
3console.log(record.changed());// false, change tracking function uses changed()
4console.log(record.getField("changed"));// true
5record.setField("changed",false);
6console.log(record.getField("changed"));// false
ChangeTracking contexts
GadgetRecord change tracking allows you to track changes on the record in different contexts. By default, all functions use the ChangeTracking.SinceLoaded context. Gadget also uses the ChangeTracking.SinceLastPersisted context to differentiate between changes that have already been persisted by the Create record and Update record effects, and changes that have been made to the record since the start of action execution.
For developers to worry less about the exact order in which their effects are run, the change tracking API assumes the ChangeTracking.SinceLoaded context by default. You may also inquire about changes since ChangeTracking.SinceLastPersisted by adding it as an option to your change tracking function calls.
19record.flushChanges(ChangeTracking.SinceLastPersisted); // this applies the current state of the record to the ChangeTracking.SinceLastPersisted change tracking context
20
21console.log(record.changed(ChangeTracking.SinceLastPersisted)); // false since these changes have been flushed
When writing custom code effects, conditions, and model field validations you have access to a shared GadgetRecord in context.
Most commonly, you will be working with the context.record inside custom code effects. Gadget will instantiate an instance of a GadgetRecord when it starts executing your action. This same instance will be shared between all validations and effects that run during that action.
The typical GadgetRecord lifecycle is as follows:
Instantiate a new GadgetRecord. All fields are undefined, no changes are tracked.
Run the Apply params effect. This effect is the first effect by default in your Create and Update actions. After this effect runs, your context.record will have changes() that correspond to the current state of the record.
Run the Create Record or Update Record effect. These effects will first validate your record and then, if valid, persist the record in your database. They will also clear the changes() state of the record after persisting it.