MaRiTg R. said: Ok, that's perfect. Thank you for the help and the explanation!! I always try to fix things myself but my understanding of repeating section is lacking at best They are pretty complex! I hope Scott will forgive me, but I've rewritten his worker without using the reduce function, so you can (hopefully) see what is happening. You can also compare the two functions, and maybe understand his function better. on ( "change:repeating_damage" , function () { getSectionIDs ( "repeating_damage" , function ( ids ) { // create an empty array to contain the attributes const getArr = []; // now loop throw the ids array, and add the attribute names to getArr; ids . forEach ( function ( id ) { // id is a sapecific row id. getArr . push ( `repeating_damage_ ${ id } _dice` , `repeating_damage_ ${ id } _dice_amount` ); }); // get all the attributes in getArr (aka all the damage info from each rowDamage) getAttrs ( getArr , ( values ) => { // create an empty array to hold the final output const attack_array = [] ; // loop through all the rows in the ids array again, to construct the output; ids . ForEach ( id => { const damageAmount = values [ `repeating_damage_ ${ id } _dice_amount` ]; //Since you're working with these as strings, there's really no need to parseInt them. const damageDice = values [ `repeating_damage_ ${ id } _dice` ]; attack_array . push ( damageAmount + damageDice ); }); // we not have an array of each row's results, but we need a string. // luckily, javascript has a function to convert arrays into strings, and put a separator between each one. const attack_string = attack_array . join ( '+' ); // now, finally we want to output the string. setAttrs ({ attack_damage : attack_string } ); }); }); }); Notice how you have two loops, first to construct an array of the attributes for getAttrs (so you only need to run getAttrs once), and a second tiime to do the actual work of building the output. The vast majority of repeating section workers can follow this model. If I were writing the function myself, my version would more closely resemble Scott's. I'm not suggesting this function as an alternative, just showing it for instructional purposes. If that repeating section grows to include more attributes, I'd change the first line of this worker to: on ( "change:repeating_damage:dice_amount change:repeating_damage:dice" , function () { That way its only being triggered by the attributes used in the worker. Also adding {silent:true} in the setAttrs seems very sensible. I tend to rely on the cascading effects of setAttrs, so don't use it as often as I should for maximum efficiency, but it seems perfect here.