State not updating in nested object

I'm making a card game and trying to make a modification on a card.
My schema struct is somewhat like that:

field -> rows -> spots -> playerCard

My problem is, when I try to modify the object, the schema don't update, but when I move my card in the field for example, the values that I applied to the card finally appears.

I'm modifying the state like that:
this.state.field.rows[rowIndex].spots[spotIndex].playerCard.modifiers.push(playerCardModifier)

One workaround that I've been using is creating and entire new spot object (parent of my playerCard) and assiging it, this way the schema is properly updated.

The workaround is like this:
const tempSpot = new FieldSpot(spot.index, spot.ownerType)
tempSpot.playerCard = spot.playerCard
this.state.field.rows[rowIndex].spots[spotIndex] = tempSpot

Is there a way to make the state update without creating a new object?
I tried cloning the object with javascript spread operator, but that don't work for schemas, since spread just copy the enumerated values of an object.

Thanks in advance.

Hi @arturspon,

Do you possibly re-use Schema instances? Depending on how the schema instance is being moved around (or re-used) within the state, the client-side callback may not trigger the way you expected, unfortunately. If you can provide a minimal reproduction example with your scenario it could help us understand the specific issue you're having.

You could potentially use spot.clone() to make sure a new object is created when sharing the instance is necessary

Hope this helps, cheers!

Hi @endel,

I'm not sure what do you mean by re-using schemas. What I have is multiple service classes to break up my code and separate pieces of logic. These services take the room and schema instance in their constructors, maybe this could be the cause of the issue?

Furthermore, I tried to use the .clone(), but I'm facing an exception when doing so. After a little bit of research I came across this issue on Github (https://github.com/colyseus/schema/issues/81). Then I removed all my constructors, but the exception still persisted, like the following:

0_1653137962249_Screenshot_2.png

For now, I'm using this workaround:
Instead of doing spot.playerCard = spot.playerCard.clone()
I do this: spot.playerCard = new PlayerCard().assign(spot.playerCard)

Thank you for your response! (and nice to see that you're brazilian, amazing job on Colyseus!!!)

@endel Hi again,

Just to give an update, the good news is that I'm not having issues anymore with state updates after using new instances everywhere.

But I still can't figure out why I'm getting errors when using the .clone function. I'm getting a null error, but my object is not null.

Anyway, I'm glad that I can make it work with the .assign() workaround for now.

Thanks!