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

Using getAttrByName() to find repeating actions floods the console with errors

1511219568

Edited 1511323543
I've made a script to automatically populate abilities for characters based on which slots in the repeating sections of the 5th Edition OGL by Roll20 are being used. It works just fine. To find which slots are being used, I pass parameters to getAttrByName() to find if a repeating action has been named. If it's been named, I then execute code to check if an ability for that character already exists, and then it makes it. It looks like this: var j = getAttrByName(o.id, "repeating_" + p + "_$" + String(i) + names[k]) I'm essentially executing getAttrByName() hundreds of times: At least once for every type of repeating section per character (repeating_npcaction, repeating_spell-cantrip, repeating_spell-1, etc.), and I have a LOT of characters in my campaign. So that means that every time it doesn't find a named action, it passes an error to the console similar to this: "ERROR: You tried to use the repeating section row at index 2 for repeating_npcaction, but there doesn't seem to be a row at that index." My console is completely flooded with this error, even though the script is working as intended. Roll20 staff: Is there anyway we can have an optional parameter in getAttrByName() to silence the warnings? Is there anything else I can do to circumvent this? And yes, I've tried making my own function as a replacement for getAttrByName() just like  here , but it will not find repeating section attributes, I'm assuming since they are technically "hidden" attributes with default values that don't actually appear in the character sheet. That function is called myGetAttrByName and is at the top of the gist I'm about to link, if you care to look. Gist here:  LINK
Could it be because one of the prefixes you are using is spell-npc and as of version 2.0 of the character sheet npc spells follow the same naming convention as PCs (i.e spell-1, spell-2, spell-3, ... spell-9)? Also, I am curious as to why are you referencing the repeating sections using getAttrByName as opposed to using filterObjs and filtering based on the name (repeating-SECTION_INDEX_ATTRIBUTE).
1511223527

Edited 1511223658
Kyle G. said: Could it be because one of the prefixes you are using is spell-npc and as of version 2.0 of the character sheet npc spells follow the same naming convention as PCs (i.e spell-1, spell-2, spell-3, ... spell-9)? Nope. It throws the error for any prefix. I did notice that about spell-npc but it was still up on the wiki  here so I left it. Guess I'll take it out if it really does nothing since my campaign isn't old enough for pre-2.0. Also, I am curious as to why are you referencing the repeating sections using getAttrByName as opposed to using filterObjs and filtering based on the name (repeating-SECTION_INDEX_ATTRIBUTE). findObjs didn't work (it's in the first function in the script) so I would assume filterObjs wouldn't work either. I can certainly try though. I'll let you know if it makes a difference. What I'd REALLY like to see is the code in the function getAttrByName(). I couldn't find it anywhere. Maybe if a dev could pm it to me ...
1511243963

Edited 1511260494
Jakob
Sheet Author
API Scripter
You cannot find repeating section attributes by row index using findObjs(); you can , however, find them by ID! Extracting which index $n they belong to however is a bit of work... . The problem with getAttrByName() is that we cannot reproduce it exactly in the API, since it also takes care of sheet default values, which are normally inaccessible in the API. To help with your original question, I struggled a bit with finding repeating rows in writing ChatSetAttr. It may be a bit overkill, but you could have a look at the getCharRepeatingAttributes function  here . The first thing it does is get all the repeating row IDs for all relevant sections in the right order. It's not documented at all, so this link would be useless. Instead, here's a rough function adapted from the above to get you all section IDs and attributes in a given section: const getRepeatingSectionAttrs = function (charid, prefix) { // Input //  charid: character id //  prefix: repeating section name, e.g. 'repeating_weapons' // Output //  repRowIds: array containing all repeating section IDs for the given prefix, ordered in the same way that the rows appear on the sheet //  repeatingAttrs: object containing all repeating attributes that exist for this section, indexed by their name const repeatingAttrs = {}, regExp = new RegExp(`^${prefix}_(-[-A-Za-z0-9]+?|\\d+)_`); let repOrder; // Get attributes findObjs({ _type: 'attribute', _characterid: charid }).forEach(o => { const attrName = o.get('name'); if (attrName.search(regExp) === 0) repeatingAttrs[attrName] = o; else if (attrName === `_reporder_${prefix}`) repOrder = o.get('current').split(','); }); if (!repOrder) repOrder = []; // Get list of repeating row ids by prefix from repeatingAttrs const unorderedIds = [...new Set(Object.keys(repeatingAttrs) .map(n => n.match(regExp)) .filter(x => !!x) .map(a => a[1]))]; const repRowIds = [...new Set(repOrder.filter(x => unorderedIds.includes(x)).concat(unorderedIds))]; return [repRowIds, repeatingAttrs]; } May contain some typos. Up to upper/lower-case issues, repeatingAttrs[`${prefix}_${repRowIds[4]}_name`] should then give the attribute object corresponding to e.g. repeating_weapons_$4_name, or undefined if an attribute object doesn't exist yet (either because the attribute hasn't been created yet, or because there are less than 5 repeating rows, which would mean that repRowIds.length < 5). Since unfortunately the handling of upper and lower case by Roll20 is terribly inconsistent, you may want to double-check repRowIds to see if it contains IDs that are the same up to case. This probably shouldn't happen, but it may. P.S.: Never use filterObjs(), you should only use findObjs() with parameters characterid and type and then filter afterwards, it's much faster, especially  in large campaigns.
Thanks Jakob!! This is really helpful stuff.
Quick update - the uppercase/lowercase issues were not present, and your code's spelling was perfect :) Took my brain a bit to figure out how to access the objects, but I got it. Nice and smooth, and the console is free of errors at last. Updated the gist if you want to see it. Thanks again!
1511291003
Jakob
Sheet Author
API Scripter
Awesome! Pro tip, because you talked about accessing the objects - while your way works fine, you can use so-called destructuring  to access them in a more straighforward way: const [IDs, attributes] = getRepeatingSectionAttrs(o.id,"repeating_" + p); That defines two new variables IDs and attributes , which are precisely what you would expect them to be.
Jakob said: Awesome! Pro tip, because you talked about accessing the objects - while your way works fine, you can use so-called destructuring  to access them in a more straighforward way: const [IDs, attributes] = getRepeatingSectionAttrs(o.id,"repeating_" + p); That defines two new variables IDs and attributes , which are precisely what you would expect them to be. Ah. That makes a lot of sense and will save me some space. Thank you!