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

[Help] Getting "RangeError: Maximum call stack size exceeded" when setting a handout notes value.

So I'm writing a small script for Pathfinder that automatically rolls survival for all party members and stores food & water stores in a Handout. It also allows me to devour a given amount of stores. I'm getting the following error RangeError: Maximum call stack size exceeded when I run the following code. <a href="https://gist.github.com/Bjorninn/5709dbf4fc0da0781" rel="nofollow">https://gist.github.com/Bjorninn/5709dbf4fc0da0781</a>... Now I know that the error happens when I try to set the value for notes in the Handout in the last line: foodStore.set("notes", content); as commenting it out fixes the error My problem is that the callback function is run after or asynchronously to whatever code follows foodStore.get so trying to do that doesn't work. Any idea how I can fix this?
1423845656
The Aaron
Pro
API Scripter
try: that.storeFoodAndWater = function(food, water) { var foodStore = findObjs({ name: spec.handoutName, _type: "handout" })[0]; if (foodStore === undefined || foodStore === null) { return; } foodStore.get("notes", function(content) { //var content = spec.cleanNotes(notes); var rationJson; if (content === "") { rationJson = {food: 0, water: 0}; } else { rationJson = JSON.parse(content); } rationJson.food = rationJson.food + food; rationJson.water = rationJson.water + water; content = JSON.stringify(rationJson); // defer setting until 100 milliseconds later. This might help get // out of whatever race condition you are in... setTimeout(function(){ foodStore.set("notes", content); },100); }); }; BTW, you can take advantage of some nice type coercion here and simplify your code... that.storeFoodAndWater = function(food, water) { var foodStore = findObjs({ name: spec.handoutName, _type: "handout" })[0]; // undefined and null both promote to false, so using foodStore in a // boolean context will evaluate to true if foodStore is defined. if ( foodStore ) { foodStore.get("notes", function(content) { //var content = spec.cleanNotes(notes); var rationJson; // empty string also promotes to false, so you can do this: rationJson = (content ? JSON.parse(content) : {food: 0, water: 0}; // javascript has shorthand operators for A = A + n, A = A - n, etc rationJson.food += food; rationJson.water += water; content = JSON.stringify(rationJson); // defer setting until 100 milliseconds later. This might help get // out of whatever race condition you are in... setTimeout(function(){ foodStore.set("notes", content); },100); }); } }; I'll be curious to hear if that fixes the issue. Might be a bug in the way the notes' get() function is calling the callback, with it relying on some state not changing after the callback executes...
1423853502

Edited 1423853514
Works like a charm! Yeah, coming from Java land I'm still learning the Javascript ropes. Did e.g. not know that one can directly evaluate variables in an if statement. Thanks a lot, this had me pulling my hair out late last night.
1423855563
The Aaron
Pro
API Scripter
No worries! If you're coming up to speed on Javascript, I highly recommend Javascript: The Good Parts by Douglas Crockford . Especially if you're coming from Java, it will accelerate you past Javascript's foibles. =D It's got a ton of great information on writing really great JS, and details on things you may not have considered coming from Java. (Certainly, closures are not something I'd ever experienced in C++!)
1423856263
The Aaron
Pro
API Scripter
One other thing since you're coming from Java: Undefined in JavaScript is very much like Null in Java from a point of view of use. Generally speaking, you never really deal with Null in Javascript if you're doing it right. undefined is the value of something that is not set (the return of a function that doesn't have a return statement, the value stored at a position in an array that has no value stored in it, etc.). Null in javascript is more of an intentional empty. You aren't really going to see it unless something consciously put it in. It's like NaN for Objects. Where as undefined means there is nothing provided, Null means there is INTENTIONALLY nothing provided. Honestly, I can't think of a good example of where and why you'd use it. (Probably because there would be better ways of handling any case I can think of than using Null). I guess the best example would be if you have an object: { booleanValue: true } and you want to create one and store it somewhere for later but without assigning it a value, you could use Null: { booleanValue: null } This would give you an object with a property named booleanValue whose value is null. If you tried to do this with undefined, you would have an object with no properties, because an undefined property does not exist, so the key is not stored. I can't think of why you might want this type of introspection, but there is probably a corner case where it makes sense (maybe to preserve the fact that you had the property? or that you need it filled in?). Also, be sure to checkout underscorejs.org, as we have access to it in the API and it is super powerful!