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

[ERROR] Cannot read property 'split' of undefined

1514478593

Edited 1514478712
Missingquery
Pro
Sheet Author
API Scripter
I get the error in the title when I run the script, but I'm not sure what's returning the error, since it's occuring in the updateStatusMarker protocol and thus obscured from view. Here is my code, if that helps: on('chat:message', function(msg) {     if (msg.type != 'api') return;     var parts = msg.content.split(' ');     var command = parts.shift().substring(1);     if (command == 'staff') {         if (parts.length < 2) {             sendChat('SYSTEM', 'You must provide a selected token id and a target token id.');             return;         }         var selectedId = parts[0];         var targetId = parts[1];         var selectedToken = getObj('graphic', selectedId);         var targetToken = getObj('graphic', targetId);         if (!selectedToken) {             sendChat('SYSTEM', 'Selected token id not provided.');             return;         }         if (!targetToken) {             sendChat('SYSTEM', 'Target token id not provided.');             return;         }         var who = getObj('character', selectedToken.get('represents'));         if (!who) {             who = selectedToken.get('name');         } else {             who = 'character|' + who.id;         }         var staffer = getObj('character', selectedToken.get('represents'));         var target = getObj('character', targetToken.get('represents')); //...objects and stats; I don't think any of these are causing the error and seem to be perfectly fine //They're referenced elsewhere in the code, though, so I wouldn't recommend running it anywhere //example object const Silence = {             name : "Silence",             type : "status",             target: [Magbd],             effect : Number(MagB.get("current")) * -1,             status: "status_interdiction",             chatmsg: targetToken.get("name") + " cannot use magic for the next turn!"         }; //list of objects const staveslist = [Heal,Mend,Physic,Recover,Fortify,Bloom_Festal,Sun_Festal,Wane_Festal,Moon_Festal,Great_Festal,Freeze,Enfeeble,Entrap,Rescue,Silence,Hexing_Rod]; //I'm pretty sure the error occurs somewhere here         if (WTypeA != "Staves/Rods"){             chatstr += "\n Weapon is not a staff!"         } else {             for (var i in staveslist){                 if (staveslist[i].name == WNameA){                     j = staveslist[i];                     //check for range                     if (((Range1A) <= (diff/70)) && ((diff/70) <= (Range2A))){                         if (j.type == "healing"){                             //Set with workers in respect to total caps                             HPVal = Number(CurrHPB.get("current")) + j.effect                             CurrHPB.setWithWorker({current: HPVal})                             chatstr += "\n" + targetToken.get("name") + " is healed for " + String(j.effect) + " HP!"                         }                         if (j.type == "status"){                             for (var a in j.target){                                 j.target[a].setWithWorker("current",j.effect)                             }                             target.set(j.status);                             chatstr += j.chatmsg                         }                     } else {                         chatstr += "\n Staff is not in range!"                     }                 }             }         }         sendChat(who, chatstr);
1514482083

Edited 1514482644
GiGs
Pro
Sheet Author
API Scripter
On thing I notice: if (WTypeA != "Staves/Rods"){ WTypeA isnt defined anywhere in the code. Also, when you really arent sure what isn't working, a good way is to enter an early "return" statement, and put some log statements before that to make sure variables are being set properly. Like so: on('chat:message', function(msg) {     if (msg.type != 'api') return;     var parts = msg.content.split(' ');     var command = parts.shift().substring(1); log("Command: " + command);     if (command == 'staff') { return; // put this anyway, to ensure the macro stops before it reaches the error. The above is just an example - experiment where to put return in the code. As long as you dont get an error, you know everything is working fine up to that point. Then when you trigger the error, put return just before that, and use log statements to check your variables are initialised and have the values you expect them to.
1514482888
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Can you post the full error you get? That would help with figuring out what is going on.
1514482949

Edited 1514482988
Missingquery
Pro
Sheet Author
API Scripter
WTypeA is one of the variables defined in the omitted 'objects and variables' section. I'll try adding some log statements and see what happens. Edit: The full error is TypeError: Cannot read property 'split' of undefined TypeError: Cannot read property 'split' of undefined at updateStatusMarker (/home/node/d20-api-server/api.js:1943:53) at TrackedObj._validateAttrs (/home/node/d20-api-server/api.js:828:17) at TrackedObj.set (/home/node/d20-api-server/api.js:858:18) at apiscript.js:950:36 at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:146:1), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:146:1), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1510:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546)
1514483982

Edited 1514484237
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Hmm, I may just not be following your code properly, but I see several issues. In your section that you think is the problem: const staveslist = [Heal,Mend,Physic,Recover,Fortify,Bloom_Festal,Sun_Festal,Wane_Festal,Moon_Festal,Great_Festal,Freeze,Enfeeble,Entrap,Rescue,Silence,Hexing_Rod]; //I'm pretty sure the error occurs somewhere here         if (WTypeA != "Staves/Rods"){             chatstr += "\n Weapon is not a staff!"         } else {             for (var i in staveslist){                 if (staveslist[i].name == WNameA){ /*I'd recommend changing to using "===" for your equivalency checks. This is a good explanation of abstract vs strict equality . I think that this equivalency issue may be the cause of your problem, because your if statements aren't actually evaluating as you think they are Also, as with your j variable below, staveslist[i] is not an object, and so doesn't actually have a name property*/                     j = staveslist[i]; //This looks like it just evaluates to a string from the staveslist array                     //check for range                     if (((Range1A) <= (diff/70)) && ((diff/70) <= (Range2A))){                         if (j.type == "healing"){ //Because j evaluates to a string, how can you reference it as an object?                             //Set with workers in respect to total caps                             HPVal = Number(CurrHPB.get("current")) + j.effect //Same thing here                             CurrHPB.setWithWorker({current: HPVal})                             chatstr += "\n" + targetToken.get("name") + " is healed for " + String(j.effect) + " HP!"                         }                         if (j.type == "status"){ //Same thing here                             for (var a in j.target){ //And here                                 j.target[a].setWithWorker("current",j.effect) //And here                             }                             target.set(j.status); //And here                             chatstr += j.chatmsg //And here                         }                     } else {                         chatstr += "\n Staff is not in range!"                     }                 }             }         } I'm not sure if any of that is causing your issue, but one thing I notice about your statusmarker setting is that I can't see where you are creating an object in the form {statusmarkers:"string of statsumarkers"}. This would prevent statusmarkers from being set. Hope that helps, Scott
1514484389

Edited 1514484545
Missingquery
Pro
Sheet Author
API Scripter
The staveslist array is full of objects, not strings, like the Silence object. I've had no problems with the script working when j.type == "healing"; it's just when it's "status" that I run into these problems, so it's able to detect the difference. Changing '==' to '===' doesn't seem to affect the error, either. As for this: one thing I notice about your statusmarker setting is that I can't see where you are creating an object in the form {statusmarkers:"string of statsumarkers"} I do actually have that here: const Silence = {             name : "Silence",             type : "status",             target: [Magbd],             effect : Number(MagB.get("current")) * -1,             status: "status_interdiction" ,             chatmsg: targetToken.get("name") + " cannot use magic for the next turn!"         }; So I guess I'm still not really sure what the problem is.
1514485158

Edited 1514485393
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Ah, ok, Missed that that was an array of constants, not strings. So, we're missing quite a bit of code then. However, in your example object of silence, you have defined the statusmarkers incorrectly for proper setting: Statusmarkers can be interacted in two different ways. (See the section on statusmarkers) By accessing the statusmarkers property directly obj.get('statusmarkers') => comma delimited list of statusmarkers obj.set({statusmarkers:"interdiction,shield,etc"}) By accessing/setting the specific statusmarker obj.get('status_red') => false/true/number; obj.set({status_red:true}) or obj.set({status_red:2}) What your obj.set expression looks like if you sub in the variable values is this: obj.set(j.status) which becomes (in the case of your silence example) obj.set("status_interdiction"). You aren't actually setting the property to anything which is probably what is causing the error in applystatusmarkers. You need to change your objects to this (using the silence example): const Silence = {             name : "Silence",             type : "status",             target: [Magbd],             effect : Number(MagB.get("current")) * -1,             status: {status_interdiction:true} ,             chatmsg: targetToken.get("name") + " cannot use magic for the next turn!"         };
1514485311

Edited 1514485690
Missingquery
Pro
Sheet Author
API Scripter
Alright, that seems to have solved it. Thank you! Edit: I have one more question, actually. In interacting with specific markers, how would I set a status with a hyphenated name, such as: status: {status_back-pain: 4} Since the - is interpreted as a minus, not being in a string, the console throws an error but I'm not sure how to list the status name in a way that the API would recognize.
1514485449
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Happy rolling
1514486467
GiGs
Pro
Sheet Author
API Scripter
Marth Lowell said: Alright, that seems to have solved it. Thank you! Edit: I have one more question, actually. In interacting with specific markers, how would I set a status with a hyphenated name, such as: status: {status_back-pain: 4} Since the - is interpreted as a minus, not being in a string, the console throws an error but I'm not sure how to list the status name in a way that the API would recognize. Have you tried enclosing it in quotes, like status: {"status_back-pain": 4}
1514488956
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
G G said: Marth Lowell said: Alright, that seems to have solved it. Thank you! Edit: I have one more question, actually. In interacting with specific markers, how would I set a status with a hyphenated name, such as: status: {status_back-pain: 4} Since the - is interpreted as a minus, not being in a string, the console throws an error but I'm not sure how to list the status name in a way that the API would recognize. Have you tried enclosing it in quotes, like status: {"status_back-pain": 4} Yep, this is how you do that