Ipywidgets: Debugging Traitlets and Backbone.js?

Created on 8 Jul 2020  路  11Comments  路  Source: jupyter-widgets/ipywidgets

Is there a simple method to debug Traitlets when creating a custom widget?

I've spent hours trying to track down why my state hasn't been updating, and it often has to do with a Traitlet not being updated because it is incompatible, or indexing that silently fails. Is this logged somewhere?

This is likely also a backbone issue. I'm mostly trying to update an array, which does not cause an event to fire:

   const idx = this.model.get("hoveredImage")
   const judgements = [...this.model.get("judgements")]

    judgements[idx][0] = 1;

    this.model.set("judgements", judgements);
    this.model.save_changes();

does not work while this does:

   const idx = this.model.get("hoveredImage")
   const judgements = [...this.model.get("judgements")]

    judgements[idx][0] = 1;

    this.model.unset("judgements", { silent: true })
    this.model.set("judgements", judgements);
    this.model.save_changes();

All 11 comments

I think the source of this may be backbone. Whenever you want changes to be synced you can't directly modify the object, instead you need to create an new object and assign that in order for the changes to be synced.

So I think you could also create a new judgements array and then only need to use set

Similar deal with traitlets on the python side - you need to create a whole new object in order for it to sync. Though you can add on the ability to detect indexing changes or be able to use append using a python mvc. For example ipycytoscape does this:
https://github.com/QuantStack/ipycytoscape/blob/61c4679b07bb820b88a7ede1bdc7c678d9c141b9/ipycytoscape/cytoscape.py#L128-L130

I don't know anything about logging though

Huh interesting, thanks for the answer! for the backbone/JS side, I made a copy of the array to try to prevent that and it still wasn't working - [...this.model.get("judgements")]

I guess logging would be the solution unfortunately.

Maybe when the typescript is transpiled to js somethink wonky happens and a new object isn't actually created?

Kinda gross but does this.model.get("judgements").concat() work?

I just gave up and went with the "unset" strategy. Really would love any form of easy debugging here :/

@cabreraalex something else I should have recommended is asking about this on the jupyter widgets gitter: https://gitter.im/jupyter-widgets/Lobby

Also maybe this would help (haven't tried it, just found by googling) https://chrome.google.com/webstore/detail/backbone-debugger/bhljhndlimiafopmmhjlgfpnnchjjbhd?hl=en

Just to keep info around in case anyone else ever stumbles on this. Post on gitter: https://gitter.im/jupyter-widgets/Lobby?at=5f1cccd5d7efe5438f204963
Somewhat related issue: https://github.com/jupyter-widgets/ipywidgets/issues/2922

The same way Traitlets does not see changes that happen internally in a list object Python side, Backbone does not see them as well in JavaScript arrays.

I did not know about this unset method, that might be the best approach I guess. The approach I had when I encountered this issue was to make a shallow copy of the list before setting the model, it works as well but it might be actually slower than your solution.

We seem to have the same issues :) I had the same problem and I pass a sliced array into the set method otherwise backbone ignores the change since it just compares the old vs the new array in its isEqual fn with a === b and returns true if you don't slice or clone the array.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

npetitclerc picture npetitclerc  路  4Comments

hangyao picture hangyao  路  6Comments

drafter250 picture drafter250  路  4Comments

pbugnion picture pbugnion  路  4Comments

aidanheerdegen picture aidanheerdegen  路  4Comments