Primary and Embedded Updates

TIL how to update embedded documents at the same time as parent documents.
game.actors.getName("Foo").update({
'data.traits.size': 'sm',
items: [ {_id: "DHXcpH7kWIWXCaSB", 'data.quantity': 80} ]
});
game.actors.getName("Foo").update({
'data.traits.size': 'sm',
items: [ {_id: "DHXcpH7kWIWXCaSB", 'data.quantity': 80} ]
});
This makes sense when you look at the data._source of the Actor and see how the items are stored there.
25 Replies
Calego
CalegoOP4y ago
Data structure for example (5e actors)
No description
Calego
CalegoOP4y ago
Since items is expected to be an embedded collection, the .update method does the dirty work of exploding out the array as individual updates automatically. Setting an array in the update method for data that isn't expected to be an embedded collection would simply override the array entirely. Interestingly, this works just fine if you have multiple objects in the updateData items array with the same _id. Presumably each one is operated on sequentially.
game.actors.getName("Blank").update({
'data.traits.size': 'sm',
items: [
{_id: "DHXcpH7kWIWXCaSB", 'name': 'Arrow +2'},
{_id: "DHXcpH7kWIWXCaSB", 'name': 'Arrow +2.1'},
{_id: "DHXcpH7kWIWXCaSB", 'name': 'Arrow +2.2'},
]
});
game.actors.getName("Blank").update({
'data.traits.size': 'sm',
items: [
{_id: "DHXcpH7kWIWXCaSB", 'name': 'Arrow +2'},
{_id: "DHXcpH7kWIWXCaSB", 'name': 'Arrow +2.1'},
{_id: "DHXcpH7kWIWXCaSB", 'name': 'Arrow +2.2'},
]
});
Resulted in an item named Arrow +2.2
Ethck
Ethck4y ago
Would it be possible to update a parent but include a new child item as well? I'm trying to limit the number of round trips to the server so if I can condense it that'd be chefkiss
Calego
CalegoOP4y ago
Pretty sure definitely yes yeah! So
Ethck
Ethck4y ago
So (based off of memory) if I call an update with data that does NOT contain an ID it usually fails. How do you get around that?
Calego
CalegoOP4y ago
if the _id is there, it's an update operation. but if not it's a create
Ethck
Ethck4y ago
ooh Sweet!
Calego
CalegoOP4y ago
So you've gotta have all the right fields present for items, that's name and type
Ethck
Ethck4y ago
That's what I was hoping.
Calego
CalegoOP4y ago
No description
Ethck
Ethck4y ago
Yeah, I just remember running into issues with update(s) and not having an _id lol.
Calego
CalegoOP4y ago
No description
Ethck
Ethck4y ago
So perfect! Thanks @calego
Leo The League Lion
@ethck gave vote LeaguePoints™ to @calego (#1 • 1258)
Calego
CalegoOP4y ago
NICE documents rock
Ethck
Ethck4y ago
definitely helps in situations like this.
Calego
CalegoOP4y ago
Ohhh ok, interesting, found this snippet:
const item = new CONFIG.Item.documentClass({name: 'Foo', type: 'feat'});
const items = this.items.map(i => i.toObject());
items.push(item.toObject());
const item = new CONFIG.Item.documentClass({name: 'Foo', type: 'feat'});
const items = this.items.map(i => i.toObject());
items.push(item.toObject());
so you could construct the ephemeral Item beforehand to more easily interact with its data, then toObject it and push that into the update data
Ethck
Ethck4y ago
What's the difference between doing CONFIG.Item.documentClass and just Item? Aren't they the same (usually)?
Calego
CalegoOP4y ago
CONFIG.Item.documentClass would get you the system's item class, e.g. Item5e
Ethck
Ethck4y ago
Ah, and I assume that's probably the more preferred route, good to know!
Calego
CalegoOP4y ago
its more bulletproof yeah, in case a system does something particular about its created items, this would run the right constructor and suchforth and so on, instead of only running the Core ones.
Ethck
Ethck4y ago
Makes sense.
Mana
Mana4y ago
BTW, this combined update is dangerous with unlinked tokens.
Ethck
Ethck4y ago
How so?
Mana
Mana4y ago
Updating single small piece of an item with it causes it to replace the entire item list with what's in the update. So you end up destroying all items and their data that you didn't include. The joys of unlinked tokens, you know.
Want results from more Discord servers?
Add your server