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

[help needed] sheetworker repeating section setAttrs() not working

1610743546
CKenny
Sheet Author
Hello and thanks in advance if you can help me, Here is my problem, I did a sheetworker to calculate damages and that part work fine the problem is when I try to use setAttrs to save it in the attribute  here is the code :  let attr = {}; Object.defineProperty(attr, `${source}weapon_real_dmg`, {     value: 'damTotal' // here as a string to make the console more readable }); console.log(attr); setAttrs(attr); getAttrs([source + 'weapon_real_dmg'], (v) => {console.log(v);}) and this is what's printed in the console : as you can see the value isn't applied  any idea why it doesn't work and how to fix it?
1610765670
GiGs
Pro
Sheet Author
API Scripter
Can you post your full sheet  worker. The code snippet you've posted above look like it might be constructed incorrectly, but I cant tell without seeing the full worker. Note that getAttrs and setAttrs are asynchronous functions, which means they dont happen in a linear sequence. To gget one to run after the other, you need to nest them inside each other using callbacks, something like this: setAttrs(attr, null, function() {     getAttrs([source + 'weapon_real_dmg'], (v) => {console.log(v);}) }); I wouldnt use defineProperty though. You can just set properties for an object doing attr[`${source}weapon_real_dmg`] =  'damTotal'; Are you intending to pass the text damTotal to the attribute here? If there's a variable named damTotal, you need to remove the quotes: attr[`${source}weapon_real_dmg`] =  damTotal;
1610767818
CKenny
Sheet Author
Thank you, I replaced defineProperty and now it work. If you still want to see the full worker, here it is : let fields = [ 'vehiclerangedweapons:V_R_weapon_dam-roll', 'vehiclerangedweapons:V_R_weapon_vengeful', 'vehiclerangedweapons:V_R_weapon_min', 'vehiclerangedweapons:V_R_weapon_max', 'rangedweapons:R_weapon_dam-roll', 'rangedweapons:R_weapon_vengeful', 'rangedweapons:R_weapon_min', 'rangedweapons:R_weapon_max', 'vehiclemeleeweapons:V_M_weapon_dam-roll', 'vehiclemeleeweapons:V_M_weapon_vengeful', 'vehiclemeleeweapons:V_M_weapon_min', 'vehiclemeleeweapons:V_M_weapon_max', 'meleeweapons:M_weapon_dam-roll', 'meleeweapons:M_weapon_vengeful', 'meleeweapons:M_weapon_min', 'meleeweapons:M_weapon_max', ]; on(fields.map(field => 'change:repeating_' + field).join(' '), (e) => {         // use regex to find repeating section ID let id = /[a-z0-9_]*_-[a-z0-9]*[rvm_]*_/.exec(e.sourceAttribute);         // dice regex let redice = /(\d+)(d\d+)((?:kh?\d+)?(?:kl\d+)?(?:dl?\d+)?(?:dh\d+)?(?:[\+|-]\d+)?)?/; // transform lower case to upper case let source = id[0].replace('v_', 'V_').replace('r_', 'R_').replace('m_', 'M_'); // to avoid retyping long strings because i'm lazy var dam = source + 'weapon_dam-roll', ven = source + 'weapon_vengeful', // crit min = source + 'weapon_min', // proven max = source + 'weapon_max'; // primitive getAttrs([dam, ven, min, max], (v) => { let dmg = redice.exec(v[dam]) ven = parseInt(v[ven], 10) || 0, min = parseInt(v[min], 10) || 0, max = parseInt(v[max], 10) || 0; let dicenum = parseInt(dmg[1], 10) || 0, dicetype = dmg[2], mod = dmg[3];                 let damTotal = '{'; for (var i = 0; i < dicenum; i++) {     if (i) damTotal += ', '     if (min) damTotal += '{';     if (max) damTotal += '{';     damTotal += '1' + dicetype;     if (ven) damTotal += 'cs>' + ven;     if (min) damTotal += ', 0d1+' + min + '}kh1';     if (max) damTotal += ', 0d1+' + max + '}kl1'; } damTotal += '}'; if (mod) damTotal += mod; console.log(v[dam], `\nwith vengeful: ${ven}\nmin: ${min}\nand max: ${max}\ntranformed to:\n` ,damTotal); let attr = {}; //Object.defineProperty(attr, `${source}weapon_real_dmg`, {value: damTotal}); attr[`${source}weapon_real_dmg`] = damTotal; console.log(attr); setAttrs(attr, null, () => {     getAttrs([`${source}weapon_real_dmg`], (v) => {console.log(v);}) // check if real_dmg was set }); }); }); PS: how do you get the sheet author badge?
1610771784
GiGs
Pro
Sheet Author
API Scripter
You get the sheet author badge when you post a sheet to the github that has your roll20 user id declared in the JSON file, and that sheet is accepted. (It takes a couple of days for the badge to show up).
1610776495

Edited 1610777031
GiGs
Pro
Sheet Author
API Scripter
There's one thing that might cause issues later on. Using upper case letters in the on(change) line will sometimes cause the attributes not to be recognised. So I'd change this line on(fields.map(field => 'change:repeating_' + field).join(' '), (e) => { to this on(fields.map(field => 'change:repeating_' + field.toLowerCase()).join(' '), (e) => { to ensure they are lower case. That's quicker than editing the various attributes in the fields variable. The case doesnt matter for the rest of your worker, it's only on the event line that it matters. Unlike the rest of the suggestions in this post, this is a recommendation you absolutely should follow.  A couple of tweaks I'd also make that aren't errors, just aesthetic differences. I wouldnt use regex for this: let id = /[a-z0-9_]*_-[a-z0-9]*[rvm_]*_/.exec(e.sourceAttribute); repeating section names always have exactly the same structure (repeating_section_id_attribute), so you can use this to grab the id let id = e.sourceAttribute.split('_)[2]; The regex might be more efficient (I don't know), I just find this more readable. It looks like every attribute there is a repeating section, so there's no need to check for errors. and maybe: let section = e.sourceAttribute.split('_)[1] Of course these aren't arrays, but you can use them to construct the /ven/etc names without having to use the let source= line. for example, instead of: let ven = source + 'weapon_vengeful' you could use let ven = `repeating_${section}_${id}_weapon_vengeful` The other (incredibly minor) optimization, I suggest is here: ven = parseInt(v[ven] , 10 ) || 0 in parseInt, the bold part is completely unneccessary on roll20. So you can do this: ven = parseInt(v[ven]) || 0 The ,10 part is the 'radix', and you only need that when working with numbers that aren't in base 10 - which is almost never the case on roll20.