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

Handout doesn't update properly

I am trying to update a handout from the api. I have been looking through the forms and Wiki until I am blue in the face. Is there some sort of 'flush' command that will cause the handout to update? What is the 'best practice' for this? I want to generate a treasure list in a handout. I am trying to write a script that reads an item from a passed in roll table and writes the item to a handout, and do this several times in a row with the same handout but different tables. I am able to get the item from the roll table and I can write it to the hand out but if I try to do it again in short order the handout doesn't get updated.
1640892996
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
It might be helpful for you to post the relevant code, for the scripters in the forum to look at. If it is too long, try a gist?
This is still pretty crude, just trying to get it to work. // THandout ////////////////////// // // !THandout --HandoutName --rTableName --comment // ////////////////////// // get the rTableItem // get the handout // update handout with rTableItem //&nbsp;&nbsp;&nbsp;&nbsp; ////////////////////// on('ready',function(){ "use strict"; on('chat:message',function(msg){ var player,handout, tableItemText, noteText; if('api' === msg.type &amp;&amp; msg.content.match(/^!THandout/) ){ if(msg.type == "api" &amp;&amp; ((msg.content.indexOf('!THandout') == 0) )) { let args = msg.content.split(/\s+--/); player=getObj('player',msg.playerid); if(player){ log("handout: " + args[1] + " table: " + args[2] + " comment: " + args[3]); handout=getHandout(args[1]); if(!handout) { return;} tableItemText=getTableItem(args[2]); if(!tableItemText) { return;} var handNotes = handout.get('notes', function(noteText) { log('noteText: ' + noteText); return noteText; }); log("handNotes: " + handNotes); // ?????????? if(tableItemText !== undefined) { log('table Item:' + tableItemText); log('old handout text:' + handNotes); if(handNotes !== undefined) { noteText=buildTextStr(handNotes, tableItemText); } else { noteText=tableItemText; } log('noteText: ' + noteText); handout.set('notes', noteText); }; var gmText = handout.get("gmnotes", function(hoText) { return hoText; }) log("gmnotes " + gmText); ////////////////////////////////////////////////////////// if(args[3] !== undefined) { if(gmText !== undefined) { handout.set('gmnotes', args[3] + " " + gmText); } else { handout.set('gmnotes', args[3]); } } }; sendChat('','/w "'+player.get('displayname')+'" Created a handout for you: &lt;a href="<a href="http://journal.roll20.net/handout/'+handout.id+" rel="nofollow">http://journal.roll20.net/handout/'+handout.id+</a>'" style="color:blue;text-decoration:underline;"&gt;Handout for '+player.get('displayname')+'&lt;/a&gt;'); } } }); }); //////////////// returns a string function buildTextStr(oldText, newText) { return oldText + " " + newText; } //////////////// returns a new handout function createHandout(handoutName) { var handout = createObj('handout',{ name: handoutName }); log("Create " + handoutName); return handout; } //////////////// returns a handout obj function getHandout(handoutName) { var handout = filterObjs(function(o){ return ( 'handout' === o.get('type') &amp;&amp; handoutName === o.get('name') &amp;&amp; false === o.get('archived')); })[0]; if(handout) { log("Found " + handoutName); return handout; } return createHandout(handoutName); } //////////////// returns an item from a rollabletable function getTableItem(tableName) { var rTableItem, rTable; var table = findTable( tableName ); if( table.length &lt; 1 ) { log('No such table exists. '); } else { return rollTableItem( table[0].id ); } } //////////////// returns a rollabletable obj function findTable( tableName ) { var rollTable = findObjs({ type: 'rollabletable', name: tableName }, { caseInsensitive: true }); return rollTable; } //////////////// returns a rollTableItem function rollTableItem( tableId ) { // Picks an item from the table var items = findObjs({ type: 'tableitem', rollabletableid: tableId }), weightedList = []; if( items.length &gt; 0 ) { _.each( items, function( item ){ // Build a weighted list to draw from let weight = item.get( 'weight' ); _( weight ).times(function( x ){ weightedList.push( item.id ); }); }); var chosenItem = getObj( 'tableitem', weightedList[ randomInteger( weightedList.length ) - 1 ] ); return chosenItem.get( 'name' ) ; } else { log( 'No items on this table.' ); } } ///////////////
1640908354

Edited 1640908384
My guess: var handNotes = handout.get('notes', function(noteText) { &nbsp;&nbsp;&nbsp;&nbsp;log('noteText: ' + noteText); &nbsp;&nbsp;&nbsp;&nbsp;return noteText; }); log("handNotes: " + handNotes); // ?????????? handout.get() returns immediately leaving you with an undefined value in the handNotes variable. The place to do something with the result of the call is inside the callback function you are handing to handout.get() --&nbsp;I imagine the value of the noteText variable there is fine and correct. Same goes for any other time you are calling .get() on a handout or character's 'notes', 'gmnotes', or 'bio'.
1640968156
timmaugh
Pro
API Scripter
Yep... That get will be asynchronous, so you'll have to handle the results in the callback (or stemming from the callback). The code looks like you know what you're doing, so just as a for instance, you can manage the second option by passing a callState variable and letting your linear code end... Picking it up on the backside of the callback and using the callState to know where you are and what you need to do.
Thank you both Jim R. and Timmaugh for the guidance. As for knowing what I'm doing.. well I don't. I retired from writing software over 20 years ago and know nothing of Java Script, (I was a C and C++ programmer).
Thank you so much for the tip that it was asynchronous, that was my biggest problem. I now have it working. The intention is to create and/or update treasure handouts. What I have so far: // THandout ////////////////////// // // !THandout --HandoutName --rTableName --comment // // initial offering by John Edsall 01 Jan 2022 // ////////////////////// // get the rTableItem // get the handout // update handout with rTableItem // ////////////////////// on('ready',function(){ "use strict"; on('chat:message',function(msg){ var player,handout, tableItemText, noteText; var version = "1.0"; if('api' === msg.type &amp;&amp; msg.content.match(/^!THandout/) ){ if(msg.type == "api" &amp;&amp; ((msg.content.indexOf('!THandout') == 0) )) { let args = msg.content.split(/\s+--/); log( args[0] + ' ver. ' + version); player=getObj('player',msg.playerid); if(player){ log("handout: " + args[1] + " table: " + args[2] + " gm comment: " + args[3]); handout=getHandout(args[1]); if(!handout) { return;} if(args[3] !== undefined) { handout.get('gmnotes', function(gmText) { if(!_.isNull(gmText)){ setTimeout(function(){ var newtext; // log('args[3]: ' + args[3]); if(gmText !== undefined &amp;&amp; gmText !== 'null') { newtext = gmText + "&lt;br&gt;" + args[3]; } else { newtext = args[3]; } handout.set('gmnotes', newtext); // update the handout gmnotes },0); } setTimeout(function(){},0); }); } tableItemText=getTableItem(args[2]); if(!tableItemText) { return;} handout.get('notes', function(noteText) { if(!_.isNull(noteText)){ setTimeout(function(){ var newtext; if(tableItemText !== undefined) { // log('handout.get table Item: ' + tableItemText); if(noteText !== undefined &amp;&amp; noteText !== 'null') { newtext = noteText + "&lt;br&gt;" + tableItemText; } else { newtext = tableItemText; } }; handout.set('notes', newtext); // update the handout notes },0); } setTimeout(function(){},0); }); }; sendChat('','/w "'+player.get('displayname')+'" Created a handout for you: &lt;a href="<a href="http://journal.roll20.net/handout/'+handout.id+" rel="nofollow">http://journal.roll20.net/handout/'+handout.id+</a>'" style="color:blue;text-decoration:underline;"&gt;Handout for '+player.get('displayname')+'&lt;/a&gt;'); } } }); }); //////////////// returns a new handout function createHandout(handoutName) { var handout = createObj('handout',{ name: handoutName }); log("Create " + handoutName); return handout; } //////////////// returns a handout obj function getHandout(handoutName) { var handout = filterObjs(function(o){ return ( 'handout' === o.get('type') &amp;&amp; handoutName === o.get('name') &amp;&amp; false === o.get('archived')); })[0]; if(handout) { log("Found " + handoutName); return handout; } return createHandout(handoutName); } //////////////// returns an item from a rollabletable function getTableItem(tableName) { var rTableItem, rTable; var table = findTable( tableName ); if( table.length &lt; 1 ) { log('No such table exists. '); } else { return rollTableItem( table[0].id ); } } //////////////// returns a rollabletable obj function findTable( tableName ) { var rollTable = findObjs({ type: 'rollabletable', name: tableName }, { caseInsensitive: true }); return rollTable; } //////////////// returns a rollTableItem function rollTableItem( tableId ) { // Picks an item from the table var items = findObjs({ type: 'tableitem', rollabletableid: tableId }), weightedList = []; if( items.length &gt; 0 ) { _.each( items, function( item ){ // Build a weighted list to draw from let weight = item.get( 'weight' ); _( weight ).times(function( x ){ weightedList.push( item.id ); }); }); var chosenItem = getObj( 'tableitem', weightedList[ randomInteger( weightedList.length ) - 1 ] ); return chosenItem.get( 'name' ) ; } else { log( 'No items on this table.' ); } } ///////////////