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

Bug with _.each

1586876349

Edited 1586876374
Alain H.
Pro
Sheet Author
API Scripter
Hi, I have a bug with the javascript of my sheet that I'm trying to update. I want to transfer data from an old system to a new one. This is a "repeating_" section. When I use my sheetworker, it is well copied, except that it is copied twice.                 getSectionIDs("repeating_slotsTete", function(idarray)                 {                                        _.each(idarray, function(currentID, i)                     {                         getAttrs(                             [                             'repeating_slotsTete_' + currentID + '_slotsUTete',                             'repeating_slotsTete_' + currentID + '_slotsNTete',                             'repeating_slotsTete_' + currentID + '_slotsATete',                             'repeating_slotsTete_' + currentID + '_slotsETete',                             'repeating_slotsTete_' + currentID + '_slotsDureeTete',                             'repeating_slotsTete_' + currentID + '_slotsDTete'                             ], function(v)                         {                             var u = v['repeating_slotsTete_' + currentID + '_slotsUTete'];                             var n = v['repeating_slotsTete_' + currentID + '_slotsNTete'];                             var a = v['repeating_slotsTete_' + currentID + '_slotsATete'];                             var e = v['repeating_slotsTete_' + currentID + '_slotsETete'];                             var duree = v['repeating_slotsTete_' + currentID + '_slotsDureeTete'];                             var d = v['repeating_slotsTete_' + currentID + '_slotsDTete'];                                                         var newrowid = generateRowID();                             var newrowattrs = {};                             newrowattrs["repeating_modules_" + newrowid + "_moduleSlotTete"] = u;                             newrowattrs["repeating_modules_" + newrowid + "_moduleNom"] = n;                             newrowattrs["repeating_modules_" + newrowid + "_moduleActivation"] = a;                             newrowattrs["repeating_modules_" + newrowid + "_moduleEnergie"] = e;                             newrowattrs["repeating_modules_" + newrowid + "_moduleDuree"] = duree;                             newrowattrs["repeating_modules_" + newrowid + "_moduleDescription"] = d;                             setAttrs(newrowattrs);                         });                     });                 }); Thank you in advance for your help.
1586879993
Andreas J.
Forum Champion
Sheet Author
Translator
So what's the bug? What is your code doing wrong, and what should it be doing? It's easier to help if people known what they are supposed to be looking at.
1586890041
Alain H.
Pro
Sheet Author
API Scripter
When I open the sheet, it copies twice what I ask it to copy, instead of once. According to the tests I've done, it does two runs on it and I can't stop it, even by putting variables to prevent it.
1586892926
GiGs
Pro
Sheet Author
API Scripter
You should never have setAttrs inside a loop if you can avoid it, and definitely shouldnt do it for every row of a repeating section. That's probably not your issue. But I'd optimise it anyway, by moving this var newrowattrs = {}; to earlier in your code, before the _.each line. And then restructuring the code so the _each() is inside the getAttrs section, so you can move this setAttrs(newrowattrs); to after the _each loop ends. Back to your original problem: You are only showing part of the code, and if its running twice, the problem might be before this. How is this being triggered? Is it a change event? What specifically is being copied twice? Are you getting each row of the section twice, in order, or do you get one complete set of rows, then another complete set of rows after it? The more info we have, the easier it will be to diagnose.
1586901452

Edited 1586901543
Alain H.
Pro
Sheet Author
API Scripter
I'll look to change the code. The total code is only slightly longer, but here it is all of it. Already is set to 0 for test purposes. Later it will be updated so that the code only runs once (for updating from an old system on the sheet to a new one, as said). on( "sheet:opened" , function() { getAttrs(['MAJMod'], function(value) { var already = 0; if(already != 1) { getSectionIDs("repeating_slotsTete", function(idarray) { _.each(idarray, function(currentID, i) { getAttrs( [ 'repeating_slotsTete_' + currentID + '_slotsUTete', 'repeating_slotsTete_' + currentID + '_slotsNTete', 'repeating_slotsTete_' + currentID + '_slotsATete', 'repeating_slotsTete_' + currentID + '_slotsETete', 'repeating_slotsTete_' + currentID + '_slotsDureeTete', 'repeating_slotsTete_' + currentID + '_slotsDTete' ], function(v) { var u = v['repeating_slotsTete_' + currentID + '_slotsUTete']; var n = v['repeating_slotsTete_' + currentID + '_slotsNTete']; var a = v['repeating_slotsTete_' + currentID + '_slotsATete']; var e = v['repeating_slotsTete_' + currentID + '_slotsETete']; var duree = v['repeating_slotsTete_' + currentID + '_slotsDureeTete']; var d = v['repeating_slotsTete_' + currentID + '_slotsDTete']; var newrowid = generateRowID(); var newrowattrs = {}; newrowattrs["repeating_modules_" + newrowid + "_moduleSlotTete"] = u; newrowattrs["repeating_modules_" + newrowid + "_moduleNom"] = n; newrowattrs["repeating_modules_" + newrowid + "_moduleActivation"] = a; newrowattrs["repeating_modules_" + newrowid + "_moduleEnergie"] = e; newrowattrs["repeating_modules_" + newrowid + "_moduleDuree"] = duree; newrowattrs["repeating_modules_" + newrowid + "_moduleDescription"] = d; setAttrs(newrowattrs); }); }); }); } }); });
1586901769
GiGs
Pro
Sheet Author
API Scripter
You shouldn't have two getAttrs statements either. I suspect the issue is this part var already = 0; if(already != 1) I'm not seeing how this would ever by 1. Is there an attribute on the sheet this is supposed to be being set to? MAJMod?
1586902569

Edited 1586903526
GiGs
Pro
Sheet Author
API Scripter
Assuming MAJMod is your attribute you want to check to see if the script should run or not, here's one way to rewrite your function, with comments to explain why its done this way. on("sheet:opened", function () {     getSectionIDs("repeating_slotsTete", function (idarray) {         var fieldnames = [];         // i'm using forEach in place of .each, because its natively supported by javascript now.         // first thing we do is loop through and get all the attribute names we need for a single getAttrs call         idarray.forEach(currentID => {             fieldnames.push(                 'repeating_slotsTete_' + currentID + '_slotsUTete',                 'repeating_slotsTete_' + currentID + '_slotsNTete',                 'repeating_slotsTete_' + currentID + '_slotsATete',                 'repeating_slotsTete_' + currentID + '_slotsETete',                 'repeating_slotsTete_' + currentID + '_slotsDureeTete',                 'repeating_slotsTete_' + currentID + '_slotsDTete'             );         });         // add the MAJMod attribute here so we dont need another getAttrs call         fieldnames.push('MAJMod');         getAttrs(fieldnames, function (v) {             // i'm assuming MAJMod is the already attribute. If its a different attribute, add it to the getAttrs call above             // and get its value here             var already = +v.MAJMod || 0;             if(already !== 1) {                 // set a variable to hold all the attributes you'll be sending to the character sheet                 // but do it before the loop - it can hold the attributes for all the rows.                 var newrowattrs = {};                 // a second each loop, to actually do the work.                 idarray.forEach(currentID => {                     var u = v['repeating_slotsTete_' + currentID + '_slotsUTete'];                     var n = v['repeating_slotsTete_' + currentID + '_slotsNTete'];                     var a = v['repeating_slotsTete_' + currentID + '_slotsATete'];                     var e = v['repeating_slotsTete_' + currentID + '_slotsETete'];                     var duree = v['repeating_slotsTete_' + currentID + '_slotsDureeTete'];                     var d = v['repeating_slotsTete_' + currentID + '_slotsDTete'];                     var newrowid = generateRowID();                     newrowattrs["repeating_modules_" + newrowid + "_moduleSlotTete"] = u;                     newrowattrs["repeating_modules_" + newrowid + "_moduleNom"] = n;                     newrowattrs["repeating_modules_" + newrowid + "_moduleActivation"] = a;                     newrowattrs["repeating_modules_" + newrowid + "_moduleEnergie"] = e;                     newrowattrs["repeating_modules_" + newrowid + "_moduleDuree"] = duree;                     newrowattrs["repeating_modules_" + newrowid + "_moduleDescription"] = d;                 });                 // save a new value for MAJMod so this doesnt run again                 newrowattrs['MAJMod'] = 1;                 // save all the attributes in one operation, once the loop has finished.                 setAttrs(newrowattrs);             }         });     }); });
1586902686
GiGs
Pro
Sheet Author
API Scripter
Not that if MajMod is a versioning attribute, and you see it changing in the future, you should change this line  if(already !== 1) { to  if(already < 1) { So that it doesnt run again when you later increase MAJMod.
1586903402
Alain H.
Pro
Sheet Author
API Scripter
Thanks for your help, but with your script I have a mistake. TypeError: fieldnames.push is not a function
1586903491
GiGs
Pro
Sheet Author
API Scripter
whoops, this line  var fieldnames = {}; should be  var fieldnames = [];
1586904230
Alain H.
Pro
Sheet Author
API Scripter
I fixed the problem. There is no more error, but the problem is there again: I don't know why, but it copies the information in duplicate. I put a log ("console.log(newrowattrs);") just before "setAttrs(newrowattrs);", and it gives this (And yes, I put it once, and got it twice in output). Object { "repeating_modules_-M4uqunjuwRA4LP6wJQC_moduleSlotTete" : "2" , "repeating_modules_-M4uqunjuwRA4LP6wJQC_moduleNom" : "Tete1" , "repeating_modules_-M4uqunjuwRA4LP6wJQC_moduleActivation" : "Te1" , "repeating_modules_-M4uqunjuwRA4LP6wJQC_moduleEnergie" : "1" , "repeating_modules_-M4uqunjuwRA4LP6wJQC_moduleDuree" : "TeDuree1" , "repeating_modules_-M4uqunjuwRA4LP6wJQC_moduleDescription" : "TEST\nTEST\nTEST\nTEST" , "repeating_modules_-M4uqunjuwRA4LP6wJQD_moduleSlotTete" : "3" , "repeating_modules_-M4uqunjuwRA4LP6wJQD_moduleNom" : "Tet2" , "repeating_modules_-M4uqunjuwRA4LP6wJQD_moduleActivation" : "Te2" , "repeating_modules_-M4uqunjuwRA4LP6wJQD_moduleEnergie" : "2" , … } Object { "repeating_modules_-M4uqunnemBdbiKbIO0F_moduleSlotTete" : "2" , "repeating_modules_-M4uqunnemBdbiKbIO0F_moduleNom" : "Tete1" , "repeating_modules_-M4uqunnemBdbiKbIO0F_moduleActivation" : "Te1" , "repeating_modules_-M4uqunnemBdbiKbIO0F_moduleEnergie" : "1" , "repeating_modules_-M4uqunnemBdbiKbIO0F_moduleDuree" : "TeDuree1" , "repeating_modules_-M4uqunnemBdbiKbIO0F_moduleDescription" : "TEST\nTEST\nTEST\nTEST" , "repeating_modules_-M4uqunnemBdbiKbIO0G_moduleSlotTete" : "3" , "repeating_modules_-M4uqunnemBdbiKbIO0G_moduleNom" : "Tet2" , "repeating_modules_-M4uqunnemBdbiKbIO0G_moduleActivation" : "Te2" , "repeating_modules_-M4uqunnemBdbiKbIO0G_moduleEnergie" : "2" , … } eval" class="frame-link-source" draggable="false">
1586904642
GiGs
Pro
Sheet Author
API Scripter
Thats weird, seems like the sheet:opened  event is being triggered twice.