Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

First time the value is changed, previousValue and newValue are the same

1630519443

Edited 1630519475
Grinning Gecko
Pro
Sheet Author
I have an input: <input type="number" name="attr_character_level" value="1" /> And a listener: on("change:character_level", (e) => { console.log(e); }); The very first time I load up a new sheet and change the value of `character_level`, `previousValue` and `newValue` are the same: { "sourceAttribute": "character_level", "sourceType": "player", "triggerName": "character_level", "previousValue": "2", "newValue": "2" } In this case, `previousValue` should be "1". Subsequent times `previousValue` is correct, but the very first time it isn't, which causes other items on the sheet to get out of sync. Is this a known issue? Is there a workaround?
1630553402

Edited 1630553913
Oosh
Sheet Author
API Scripter
Scott C has a pretty good handle on the HTML => sandbox => firebase interconnectedness of things and might have a good explanation, but as a workaround you might need to use a sheetworker to set the initial value instead of HTML. Just a quick on('sheet:opened'), check if the attribute exists (get rid of the HTML default to avoid confusion), and initialize it if it doesn't. This should ensure that it's set properly by firebase in the character sheet's .attribs. edit - Yep, just made a new character from my own sheet. The only attributes which exist on firebase are those initialised by my sheet:opened function. None of the HTML defaults exist on the sheet, and function however "default attributes" function - something in Roll20's attribute parser points the @{reference} toward the default value instead of fishing it from the .attribs object. This parsing doesn't happen for the event object, so it does its "this is a new attribute" routine, which is previousValue = newValue. I'm not sure why it's done this way instead of prev being null , but since a change event doesn't fire unless the value changes, an exact equality match is logically as good as a previousValue === null, in terms of checking if an attribute was just created (I think!)
1630596960

Edited 1630598919
GiGs
Pro
Sheet Author
API Scripter
Grinning Gecko said: Is this a known issue? Is there a workaround? Yes, this is a known problem, and pretty irritating. I don't use newValue very often - for a long time it didn't work with API scripts, I don't know if that's still true, but I got in the habit of not using it unless there was another way, so I'm not very experienced with it. Maybe Scott has a better approach. But my method to handle this problem is to include a logical step based on if(event.newValue === event.previousValue) The trick is: if this worker is doing something, a change event has fired, so a change must have occurred. If the previousvalue and newvalue are equal, that means this must be the first time the attribute has changed, because the only time they are equal and a change event is occurring, is because its the first time that attribute is changing. So you can use this to build in any logic you need to handle that. Oosh's first paragraph also includes a good work around. I imagine you could set up a worker that sets all default values once, and also sets another value "check_defaults". On each sheet opened, it checks this value, and if true or 1, or just not undefined or whatever, it doesn't run setAttrs. So you could have a single sheet worker with simple logic that sets all defaults and runs only once.
Thanks folks. I went with the "easier" solution for now of just checking if new and previous values are equal. Tangentially related, is there a bug tracker somewhere that we can see known issues and report new ones?
1630617975
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Well, late to the party, but GiGs and Oosh have pretty much covered everything I would have said. My only addition is that I have yet to find a situation where using newValue/previousValue actually provides a noticeable benefit to processing speed. I'm just not sure that it's worth all the headaches that come with using it.
1630626142
GiGs
Pro
Sheet Author
API Scripter
Scott C. said: My only addition is that I have yet to find a situation where using newValue/previousValue actually provides a noticeable benefit to processing speed. I'm just not sure that it's worth all the headaches that come with using it. Good to know that my habit of avoiding it isn't a waste of time!
Scott C. said: My only addition is that I have yet to find a situation where using newValue/previousValue actually provides a noticeable benefit to processing speed. I'm just not sure that it's worth all the headaches that come with using it. I'm not sure I understand this. I'm not using it for a performance boost. I'm using it because there are skills that aren't necessarily at the same level as the character, but when the character level changes, the skills need to change by the same amount. So I need to know what the delta is in the level change in order to apply the same to the skills.
1630636738
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Right, but I'd typically just get the values of all the attributes that affect those skill values and then recalculate them. In theory the newValue/previousValue properties of the event would be a better choice, however as you've discovered there's issues with what values are actually passed in some circumstances. Addtionally, as GiGs mentioned earlier API generated changes wouldn't provide a new/previousValue for a long time (I haven't had time to check if this is still the case) and depending on how a given API script is constructed, it's even possible for the API to cause a change that doesn't trigger an event in the sheetworkers, which would cause your values to desync. Essentially, you get a little ease of coding in exchange for a much more fragile calculation that can break for several reasons.
It might be a good idea to mention this here -&nbsp; <a href="https://wiki.roll20.net/Sheet_Worker_Scripts#Events" rel="nofollow">https://wiki.roll20.net/Sheet_Worker_Scripts#Events</a>. &nbsp;As a new sheet developer, I had no idea that documented properties could be flakey. It would be good to know that from the beginning, rather than once dependencies are built up.