T
TyphonJS•15mo ago
Forien

TJSDocument not working properly with Module Sub-Types (Data Models)

In Foundry, modules can define a Sub-Types using Data Models. On Data Models we can also define functions. We can also update the parent document using this.updateSource(), for example:
export default class MyCustomDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;

return {
customField: new fields.StringField({}),
}
}

updateField(value) {
this.updateSource({customField: value});
}
}
export default class MyCustomDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;

return {
customField: new fields.StringField({}),
}
}

updateField(value) {
this.updateSource({customField: value});
}
}
this however, does not update TJDocument and does not update the Store. Changing the function to updating the parent, however, works:
updateField(value) {
this.parent.update({"system.customField": value});
}
updateField(value) {
this.parent.update({"system.customField": value});
}
From what I can tell, the DataModel#updateSource does not call any Hooks, which might be why. I think it's worth investigating if there is a way of making DataModel#updateSource triggering the Store in TJSDocument to update.
3 Replies
TyphonJS (Michael)
TyphonJS (Michael)•15mo ago
I'll have to look into this. As things go the TJSDocument wrapper is fragile as it relies on the loose render callbacks in ClientDocumentMixin. If I had to guess offhand when the sub-types functionality was added the underlying support via updateSource doesn't fire render callbacks. Potentially this can be framed as an oversight from the implementation, but a bit of investigation is necessary before this can be claimed; it is however what I suspect could be the likely culprit. If so a case can be made to change this. There is no official event system in the Foundry data / document model. It's sort of a hack as TJSDocument registers / spoofs the hookups that apps can make to ClientDocumentMixin. It acts like an app and gets render callbacks for normal C(R)UD updates. In an ideal scenario for v12 / App v2 it would be super fantastic if a real minimal event system was added to the document model. I want to propose this, but we'll see if the core team is interested in discussion. Something very much like the minimal store contract of Svelte. IE a readable store is a basic observable essentially; provide a subscribe method that takes a callback returning an unsubscribe function is about as minimal of an event system that is needed. It would really strengthen the document model. The current solution for apps to directly register w/ the document model was an initial hack made for App v1 way back when and has lingered.
Forien
ForienOP•15mo ago
I found out that the DataModel#updateSource only updates local copy with no propagation to the database, and it does not call any Hooks or cause any renders. So yeah, that's why. I asked on Foundry's Discord if that's intended. For now I guess I will do this.parent.update then
TyphonJS (Michael)
TyphonJS (Michael)•15mo ago
OK... I've just been looking through the source for DataModel and updateSource. I haven't worked w/ this area of Foundry much since I don't work on a game system and module sub-types is new / first opportunity for module devs to dive into this area of Foundry; always a trailblazer you are.. 😉 DataModel is the base class for Document and in commons. Code shared with the client & server. The callbacks that TJSDocument relies upon is client side only via ClientDocumentMixin. It does make sense that DataModel will have no knowledge of the client side. It will be interesting to see the responses to your question of the use case for updateSource since it doesn't do a DB transaction / invoke the update chain.
Want results from more Discord servers?
Add your server