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

Automatic sheet worker issues

1685181699
Paul V.
Pro
Sheet Author
Compendium Curator
Hi All Trying to do my first more complex automatic sheet worker for a number of statistic based fields  I have four fields StrengthPri, StrengthSec, StrengthTer and StrengthTar for each statistic, attempting to use this sheet worker to use and update [stat]Tar... not sure what i'm doing wrong const stats = ['Strength','Dexterity','Constitution','Intelligence','Wisdom','Charisma']; stats.forEach(function (stat) { on("change:" + stat + "Pri change:" + stat + "Sec change:" + stat + "Ter sheet:opened", function () { getAttrs([stat+'Pri'],[stat+'Sec'],[stat+'Ter'],"pritarget","sectarget","tertarget", function (values) { const statTer = parseInt(values[stat+'Ter'])||0; const statSec = parseInt(values[stat+'Sec'])||0; const statPri = parseInt(values[stat+'Pri'])||0; const PriTar = parseInt(values.pritarget) || 0; const SecTar = parseInt(values.sectarget) || 0; const TerTar = parseInt(values.tertarget) || 0; var Target = 18; if (statTer == 1 ) { Target = TerTar;} if (statSec == 1 ) { Target = SecTar;} if (statPri == 1 ) { Target = PriTar;} setAttrs({ [stat + 'Target']: Target }); }); }); });
1685199014
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
There are a couple issues here. The listener usually requires all lowercase. Using uppercase attribute names can cause random failures. This is one of many reasons why the best practice for attribute naming is to use snake_case  which is all lower case and uses an underscore to separate words in multi word attribute names. The getAttrs call is incorrect, you need all attribute names in a single array. Your call has several arrays, and several names outside of an array. I'd recommend using template literals to do your string concatenation Taken all together, that would look like: const stats = ['wtrength','dexterity','constitution','intelligence','wisdom','Charisma']; const subStats = ['pri','sec','ter']; stats.forEach(function (stat) { // Also switching this to iterate over the sub stat appends. subStats.forEach(sub =>{ on(`change:${stat}${sub}`,(event)=>{ getAttrs([`${stat}pri`,`${stat}sec`,`${stat}ter`,"pritarget","sectarget","tertarget"], function (values) { // Creating an empty object to accumulate our changes allows // us to easily assemble the object to use in setAttrs // This isn't absolutely required for this, but is good practice nonetheless. const setObj = {}; const statTer = parseInt(values[`${stat}ter`])||0; const statSec = parseInt(values[`${stat}sec`])||0; const statPri = parseInt(values[`${stat}pri`])||0; const PriTar = parseInt(values.pritarget) || 0; const SecTar = parseInt(values.sectarget) || 0; const TerTar = parseInt(values.tertarget) || 0; // Because we created the setObj above, we can just apply the target // directly to the object setObj[`${stat}target`] = 18; // These should be done as an else if to limit the logic that has to be run through // I've also changed your equality check to use strict equality, rather than the type coercive equality. if (statPri === 1 ) { setObj[`${stat}target`] = PriTar; } else if (statSec === 1 ) { setObj[`${stat}target`] = SecTar; } else if (statTer === 1 ) { setObj[`${stat}target`] = TerTar; } setAttrs(setObj); }); }); }); });
1685261856
Paul V.
Pro
Sheet Author
Compendium Curator
thank you, that is awesome, gives me a basis to take further.