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

Firing sheet worker change event on charset API

I have an API which issues a series of charsetAttr commands. Params.dice_pool is an array of attribute value pairs, character_id is worked out earlier in the code. The code does for (key of Object.keys(params.dice_pool)) {     sendChat('API', "!setattr --charid "+ character_id + " --" + key + "_show|inactive"); } This generates well formed !setattr commands and all the relevant attributes are set to inactive.  However there is a sheet worker which is supposed to react to this change.     on('change: <a list of all the attributes that the API above can set>',(event)=>{        console.log('fired event');         var mod_name = event.sourceAttribute.split("_")         if (event.newValue ==='inactive') {             let attr_to_set = {};             attr_to_set[mod_name[0]] = '0';             setAttrs(attr_to_set);             }      }); This is supposed to un-check a checkbox on the sheet with a related name and do some other things which aren't relevant. I've checked " Trigger sheet workers when setting attributes:"   in charsetAttr. The sheet worker operates normally when the attribute is changed by hand. When the API changes the value it doesn't fire at all ("event fired" isn't written to the console). Am I missing some secret sauce to get this to fire? I came up with this pattern because trying to set the checkbox attribute directly to 0 from the API with  sendChat('API', "!setattr --charid "+ character_id + " --" + key + "|0"); gave an error 
1593696302
The Aaron
Roll20 Production Team
API Scripter
I haven't messed much with the setWithWorker() stuff.  Last I remember, this functionality was broken in some cases, but I might remember incorrectly. What was the error you got with setting the checkbox directly?
1593700593

Edited 1593700938
A classic, when I say sendChat("API", "!setattr --charid "+ character_id + " --" + key + "|0");  Where 'key' is the attribute which is attached to a checkbox control.  This sends the following example text ! setattr --charid -MAL0VJMcSHie8sWxbGY --resource1a|0   which I think is well formed. I get.  TypeError: Cannot read property 'toLowerCase' of null TypeError: Cannot read property 'toLowerCase' of null at /home/node/d20-api-server/api.js:3572:26 at Function.each (/home/node/d20-api-server/node_modules/underscore/underscore.js:188:9) at Worker.onmessage (/home/node/d20-api-server/api.js:3566:13) at ChildProcess.<anonymous> (/home/node/d20-api-server/node_modules/tiny-worker/lib/index.js:90:21) at ChildProcess.emit (events.js:310:20) at emit (internal/child_process.js:876:12 at processTicksAndRejections (internal/process/task_queues.js:85:21)
1593704629
The Aaron
Roll20 Production Team
API Scripter
Try: ! setattr --charid -MAL0VJMcSHie8sWxbGY --resource1a|"0"
1593705129

Edited 1593705298
Same error even if I drop the string into chat manually.
1593706102
The Aaron
Roll20 Production Team
API Scripter
hmm.  I'll have to look at ChatSetAttr, it might be turning it into a number.  Basically, all attributes from the point of view of Roll20 code are strings.  When you change them to numbers, it's usually fine, but sometimes there are places that it assumes they will be strings and calls string methods on something with a different type.  I'm thinking this might be that case.
1593773369

Edited 1593776211
I've been investigating this further. The issue isn't setting the attribute per se, it's setting an attribute which has an associated on("change: sheetworker. that throws the error. I've tried rewriting the sheetworker so it doesn't need any event data. e.g. on('change:resource1a_show',function(){         console.log('fired resource1a.show event');         getAttrs(["resource1a_show"], function(values) {             if (values.resource1a_show ==='inactive') {                 setAttrs({"resource1a": '0'});                 }         });     }); The API code runs if I comment this and throws the error above (and fails to set resource1a_show to inactive) if I reinstate it. Manually changing the values of resource1a_show triggers it fine. Is this a known limitation?
1593791374

Edited 1593791549
Jakob
Sheet Author
API Scripter
event.newValue and event.previousValue are definitely broken in API-sheetworkers. ChatSetAttr would not turn stuff into a number unless it has to, so I don't think TheAaron's suggestion is the root cause. James, you are saying that the sheet worker above will throw an error when you set the resource1a_show attribute using ChatSetAttr? Side remark: I'm not sure if triggering ChatSetAttr using chat commands sent by an API script is really best practice (though it should not matter here). Why don't you set the attributes directly in the API? It is a bit subtle if there are repeating fields and such involved, but this seems relatively straightforward.
I tried to do this in the API             var matched_attribute = findObjs({type:'attribute',name:key+"_show",characterid:character_id})[0]         getObj("attribute", matched_attribute.id).setWithWorker({current: "inactive"}); to set the attribute, but I got the same kind of error.  It's not easy for me to tell what's throwing the error, (it appears in the API console) but I think it is the API script. If I comment out the getObj line it runs OK. None of the console.log statements in the sheetworker with on ("change resource1a_show" appear. Using ChatSetAttr, was plan B in the hope that it might work, but it seems to hit the same problem.
1593809644
Jakob
Sheet Author
API Scripter
I can't reproduce this at all. I have the following sheet code: <input type="text" name="attr_resource1a"/> <input type="text" name="attr_resource1a_show"/> <script type="text/worker"> "use strict"; on('change:resource1a_show',function(){ console.log('fired resource1a.show event'); getAttrs(["resource1a_show"], function(values) { if (values.resource1a_show ==='inactive') { setAttrs({"resource1a": '0'}); } }); }); </script> If i run !setattr --sel --resource1a_show|inactive In chat, it does exactly the right thing. I haven't tried sending this from an API script.
I don't know what to say obviously there is something more complex going on than I thought and the root issue is elsewhere. I could share the game that I created this in, it only exists as a testbed for the sheet/API.&nbsp; &nbsp;Or the character sheet and api elements are in a git fork of the main character sheet repo at&nbsp;<a href="https://github.com/Nyarlathotep3001-source/roll20-character-sheets" rel="nofollow">https://github.com/Nyarlathotep3001-source/roll20-character-sheets</a>.