I've asked this question before, and got an answer but I'm going to try to articulate it better this time. I have a TitleData JSON object with about 20 nested keys. These are the first two out of twenty,
{ "Settler": { "id": 0, "rating": 0, "ratingTop": 49, "nextClass": "Rebellious" }, "Rebellious": { "id": 1, "rating": 50, "ratingTop": 99, "nextClass": "Fugative" }, }
Each player has a "Rating" statistic which has a rule in automation to call a cloudscript everytime the "Rating" statistic changes. My cloudscript function is below. It is messy... however its been changed a lot, trying to get different results.
handlers.UpdateSocialClass = function (args) { //Get current socialclass stored in currentSocialClass readonlydata var dataRequest = { PlayFabId: currentPlayerId, Keys: ["SocialClass"] }; var currentSocialClass = server.GetUserReadOnlyData(dataRequest); //get current rating stored in the var currentRating var statsRequest = { PlayFabId: currentPlayerId, StatisticName: "Rating", }; var currentRating = server.GetPlayerStatistics(statsRequest); //Get the title data for SocialClasses, stored in jsonObject var getTitleDataRequest = "SocialClasses"; var getTitleDataResponse = server.GetTitleData(getTitleDataRequest); //Access current class within the JSON object var yourSocialClassJson = getTitleDataResponse[currentSocialClass]; //Access ratingtop within the current class jsonObject var ratingCap = yourSocialClassJson.ratingTop; //If they have enough rating level up if(currentRating > ratingCap) { var newClass = yourSocialClassJson.nextClass; //set userdata to new class dataPayload["SocialClass"] = newClass; var result = server.UpdateUserReadOnlyData({ PlayFabId: currentPlayerId, Data: dataPayload }); } else { // If they have less than required amount then DownGradeSocialClass } }
In PlayStream it says my error is
"Error": "JavascriptException", "Message": "JavascriptException", "StackTrace": "TypeError: Cannot read property 'ratingTop' of undefined\n at handlers.UpdateSocialClass (95E3-main.js:89:41)"
I know this is most likely an easy fix. I assume my syntax is wrong when I get the title data or when I try to access the different values in title data. Debugging on cloudscript is a little difficult for me. Is there an easier way rather than playstream?
Answer by v_humcin · Jun 24, 2019 at 04:19 PM
The title data returned in the "GetTitleDataResult" is stored in an object called "Data" so based on your code the call should look something like this:
var yourSocialClassJson = getTitleDataResponse.Data[currentSocialClass];
If this does not fully fix the issue just let us know!
I changed the syntax the above line ^ and I still get the same error, Cannot read property 'ratingtop' of undefined.
In the playstream Event JSON it says i made 3 API calls so that would mean the title data request is fine, theres a problem with either of these lines from my understanding.
var yourSocialClassJson = getTitleDataResponse.Data[currentSocialClass]; var ratingCap = yourSocialClassJson.ratingTop;
Looking at it further there are a few other small adjustments that need to be made. "Data" does not directly contain the different social classes, you will have to access the "SocialClasses" value from "Data" before you can can access the other data. This is because GetTitleData will always return a dictionary of values even if you specify only one key.
Next you will need to make sure to parse the value obtained from "SocialClasses" as it is stored as a string in title data. After that that you should be able whichever class you need by name. I used "Rebellious" during testing but that's where you would use "currentSocialClass".
var getTitleDataRequest = "SocialClasses"; var getTitleDataResponse = server.GetTitleData(getTitleDataRequest); //Access current class within the JSON object var SocialClassJson = getTitleDataResponse.Data["SocialClasses"]; //Parse the result and then access current class within the JSON object var parsed = JSON.parse(SocialClassJson); var yourSocialClassJson = parsed[0]["Rebellious"];
There was a quirk I noticed where your supplied JSON title data object is being returned as an array with one entry, so to actually access the classes it has to be accessed as "parsed[0]" as you can see in my example. I am doing more testing as to why this is happening as it does not seem to be intended, but for now this example should help you to understand the flow better.
Looking at the script again I noticed that you will need to make a small change to how you are accessing the GetUserReadOnlyData. Like with GetTitleDataResponse the data itself is stored within a "Data" object which in turn holds "UserDataRecord". You would then use the value field to get the desired value out. Looking through the documentation I linked can help you understand the exact relationship between the fields and how to access the value. Within your current setup, it would look something like this to get the final value out:
currentSocialClass.Data["SocialClass"].Value
As far as debugging in cloud script goes, using log.debug() statements is a good option. It would be helpful to add checks to api calls you make to determine their status. For instance you might have a check like this after calling GetTitleData:
if (getTitleDataResponse.error != null) { log.debug(error.message); }
You can read more about this here: https://docs.microsoft.com/en-us/gaming/playfab/features/automation/cloudscript/writing-custom-cloudscript#advanced-debugging-cloudscript
Answer by David Jones · Jun 26, 2019 at 02:43 AM
An update - Everything works fine now although the only problem is the max API calls per cloudscript call. Unfortunately i have to abandon this feature because of the limitations but thank you, it made me understand better.
Cloudscript request arguments in playstream 1 Answer
What is the execution time limit for a Cloud Script function called From a Task? 1 Answer
CloudScript: How can I mark suspicious players? 1 Answer
Cloud Script Logs - Server/Events Only (don't send to client) 1 Answer
Server authentication for Cloud Scripts and PlayStream events 1 Answer