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

Undefined amounts from repeating sections

I'm having some trouble with updating a readonly field within a repeating section called "weapons" that displays the sum of the player's total base attack bonus (BAB), size modifier, and, depending on the selection of the attack modifier select field (it can be STR, CON, DEX, INT, WIS, or CHA), adds that associated amount to the sum as well. The problem lies in that, when executing the code below, it seems to routinely run out of bounds with the for loop. An example of this would be having an idarr (amount of rows) length of 2, and the function attempts to mistakenly instantiate idarr[2], leading to an undefined amount, thus not updating the amount since it cannot fetch the row ID. Am I overlooking something here? on("change:str-mod change:dex-mod change:con-mod change:int-mod change:wis-mod change:cha-mod change:total-bab change:size-mod-atk", function() { getSectionIDs("repeating_weapons", function (idarr) { for (var i = 0; i < idarr.length; i++) { getAttrs(["repeating_weapons_" + idarr[i] + "_weapon-attack-modifier", "total-bab", "size-mod-atk", "str-mod", "dex-mod", "con-mod", "int-mod", "wis-mod", "cha-mod"], function (values) { var attackModifier = values[Object.keys(values)[0]]; // select field var attackBonus = parseInt(values["total-bab"]) + parseInt(values["size-mod-atk"]); switch (attackModifier) { case "STR": attackBonus += parseInt(values["str-mod"]); break; case "DEX": attackBonus += parseInt(values["dex-mod"]); break; case "CON": attackBonus += parseInt(values["con-mod"]); break; case "INT": attackBonus += parseInt(values["int-mod"]); break; case "WIS": attackBonus += parseInt(values["wis-mod"]); break; case "CHA": attackBonus += parseInt(values["cha-mod"]); break; default: attackBonus = -1; } var attrs = {}; attrs["repeating_weapons_" + idarr[i] + "_weapon-attack-bonus"] = attackBonus; setAttrs(attrs); }); } }); });
1504403140
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
I'd log idarr and see what is in there.
I've added a statement to log the values right before setAttrs is called with them. Here is the updated code: on("change:str-mod change:dex-mod change:con-mod change:int-mod change:wis-mod change:cha-mod change:total-bab change:size-mod-atk", function() { getSectionIDs("repeating_weapons", function (idarr) { for (var i = 0; i < idarr.length; i++) { getAttrs(["repeating_weapons_" + idarr[i] + "_weapon-attack-modifier", "total-bab", "size-mod-atk", "str-mod", "dex-mod", "con-mod", "int-mod", "wis-mod", "cha-mod"], function (values) { var attackModifier = values[Object.keys(values)[0]]; var attackBonus = parseInt(values["total-bab"]) + parseInt(values["size-mod-atk"]); switch (attackModifier) { case "STR": attackBonus += parseInt(values["str-mod"]); break; case "DEX": attackBonus += parseInt(values["dex-mod"]); break; case "CON": attackBonus += parseInt(values["con-mod"]); break; case "INT": attackBonus += parseInt(values["int-mod"]); break; case "WIS": attackBonus += parseInt(values["wis-mod"]); break; case "CHA": attackBonus += parseInt(values["cha-mod"]); break; default: attackBonus = -1; } var attrs = {}; log("SETTING ROW #" + i + "; ID: " + idarr[i] + "; ATTACK BONUS: " + attackBonus); attrs["repeating_weapons_" + idarr[i] + "_weapon-attack-bonus"] = attackBonus; setAttrs(attrs); }); } }); }); Among the typical flood of statements from Roll20, the respective code produced the following output when working with 2 rows of the weapons repeating section (it was triggered by a change in any of the ability modifiers): SETTING ROW #2; ID: undefined; ATTACK BONUS: 4 SETTING ROW #2; ID: undefined; ATTACK BONUS: 7
1504408260
chris b.
Pro
Sheet Author
API Scripter
you can't have your getAttrs inside the loop that increments i, because getAttrs is asynchronous . So when the callback function (the 2nd variable of getAttrs) is called, i is something else entirely. You can break out getAttrs into a different function , like : (though instead of a for loop you can use foreach, and pass the actual ID instead of the index) function doMystuff(idarr,i) { getAttrs(["repeating... }); } on("change:str-mod ... for (var i = 0; i < idarr.length; i++) { doMyStuff(idarr,i); } });
That seems to be the problem -- It completely escaped my mind that getAttrs is asynchronous. Thanks for the help, Chris!