question

Kim Strasser avatar image
Kim Strasser asked

CloudScript: JavascriptException in for loop

I need to update the value of the achievement "Level1FinishTimes" with server.UpdateUserReadOnlyData(MyRequest); before I call ChooseanAchievement() for the next key/value pair.

For example, it's necessary that the achievement "Level1FinishTimes" is already updated before I call

ChooseanAchievement()-->case "Finish level 1 three times". Because I need to check in case "Finish level 1 three times" if ((Number(resultdatalevel1finish.Data.Level1FinishTimes.Value) >= 3).

But I get a JavascriptException in my for loop:

"Error": {
            "Error": "JavascriptException",
            "Message": "JavascriptException",
            "StackTrace": "TypeError: Cannot read property 'achievement' of undefined\n    at handlers.UpdateAchievementsReadOnlyData (BFD0A-main.js:24:34)\n    at Object.invokeFunction (Script:116:33)"
        }

What is wrong with "newAchievements[key].achievement" in my for loop?

handlers.UpdateAchievementsReadOnlyData = function (args, context)
{
    var achievementObject = args.AchievementObject;
    var achievementKeys = [];
    var newAchievements = [];
 
    for (var key in achievementObject)
    {
        achievementKeys.push(key);
    };
 
    log.info(achievementKeys);
 
    var getUserReadOnlyDataResult = server.GetUserReadOnlyData({ PlayFabId: currentPlayerId, Keys: achievementKeys });
 
    for (var key in achievementObject)
    {
        log.info("achievementObject[key]--->" + achievementObject[key]);
        newAchievements.push(ChooseanAchievement(getUserReadOnlyDataResult, key, achievementObject[key]));
  //  };
 
 //   for (var key in newAchievements)
   // {
        if (newAchievements[key].achievement != "")
        {
            log.info("newAchievements.achievement " + newAchievements[key].achievement, "newAchievements.addvalue " + newAchievements[key].addvalue);
            var MyRequest = {
                PlayFabId: currentPlayerId,
                Data: {},
                Permission: UserDataPermission.Public
            };
 
            MyRequest.Data[newAchievements[key].achievement] = newAchievements[key].addvalue;
            server.UpdateUserReadOnlyData(MyRequest);
 
            log.info("Updating achievement " + newAchievements[key].achievement + " was succuessful.");
        }
        else
        {
            log.info("Could not find this achievement.");
        }
    };
}

function ChooseanAchievement(result, achievementkey, achievementvalue)
{
    switch (achievementkey)
    {
        case "Level1FinishTimes":
            if (result.Data.hasOwnProperty(achievementkey))
            {
                if ((result.Data[achievementkey].Value != null) && (result.Data[achievementkey].Value != ""))
                {
                    if (Number(achievementvalue) == 1)
                    {
                        log.info("Level1FinishTimes ok" + achievementkey + achievementvalue);
                        return { achievement: achievementkey, addvalue: Number(result.Data[achievementkey].Value) + Number(achievementvalue) };
                    }
                    else
                    {
                        log.info("Level1FinishTimes" + achievementkey + achievementvalue);
                        return { achievement: achievementkey, addvalue: result.Data[achievementkey].Value };
                    }
                }
                else
                    return { achievement: "", addvalue: false };
            }
            else
                return { achievement: "", addvalue: false };
            break;
 
        case "Finish level 1 three times":
            var resultdatalevel1finish = server.GetUserReadOnlyData({ PlayFabId: currentPlayerId, Keys: ["Level1FinishTimes"] });
 
            if (resultdatalevel1finish.Data.hasOwnProperty("Level1FinishTimes"))
            {
                if ((resultdatalevel1finish.Data.Level1FinishTimes.Value != null) && (resultdatalevel1finish.Data.Level1FinishTimes.Value != ""))
                {
                    if ((Number(resultdatalevel1finish.Data.Level1FinishTimes.Value) >= 3)  && (achievementvalue == true))
                    {
                        log.info("Finish level 1 three times ok" + achievementkey + achievementvalue);
                        return { achievement: achievementkey, addvalue: achievementvalue };
                    }
                    else
                    {
                        log.info("Finish level 1 three times" + achievementkey + achievementvalue);
                        return { achievement: achievementkey, addvalue: result.Data[achievementkey].Value };
                    }
                }
                else
                    return { achievement: "", addvalue: false };
            }
            else
                return { achievement: "", addvalue: false };
            break;
    }
}
CloudScript
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Sarah Zhang avatar image
Sarah Zhang answered

In your code, all keys of the array achievementObject will be the key that you used in the statement on line 24 newAchievements[key].achievement != "". The array newAchievements is returned by ChooseanAchievement(getUserReadOnlyDataResult, key, achievementObject[key]) function, the array achievementObject equals to the key-value pairs args.AchievementObject, so the keys of achievementObject and them of newAchievements would not be corresponding.

The achievementObject and newAchievements are both JavaScript array. But the indexes(keys) of achievementObject are string, the indexes(keys) of newAchievements are int.

The keys of achievementObject are “Finish level 1”, “Finish level 1 three times”, “Get 10.000 points”, “Kill all enemies in this level”, the keys of newAchievements are 0,1,2,3. You can log the keys of these two arrays to check them. Hence, the keys of achievementObject can’t be used to access the newAchievements[key], newAchievements[key].achievement should be undefined. You can refer to the following code to log and compare their indexes.

for (var key in achievementObject) {
    log.info("Keys of achievementObject--->" + key);
    newAchievements.push(ChooseanAchievement(getUserReadOnlyDataResult, key, achievementObject[key]));
};




for (var key in newAchievements) {

    log.info("Keys of newAchievements--->" + key);

};

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Kim Strasser avatar image Kim Strasser commented ·

Ok, I understand. I thought the keys of newAchievements would be exactly the same keys than the keys of achievementObject(“Finish level 1”, “Finish level 1 three times”, ...).

In addition, I have successfully changed my code:

for (var key in achievementObject)
{
    newAchievements.push(ChooseanAchievement(getUserReadOnlyDataResult, key, achievementObject[key]));
    const maxIndex = newAchievements.length - 1;
       
    if (newAchievements[maxIndex].achievement != "")
    {
        log.info("newAchievements.achievement " + newAchievements[maxIndex].achievement, "newAchievements.addvalue " + newAchievements[maxIndex].addvalue);          
        var MyRequest = {
                PlayFabId: currentPlayerId,
                Data: {},
                Permission: UserDataPermission.Public
            };
 
        MyRequest.Data[newAchievements[maxIndex].achievement] = newAchievements[maxIndex].addvalue;
        server.UpdateUserReadOnlyData(MyRequest);
 
        log.info("Updating achievement " + newAchievements[maxIndex].achievement + " was succuessful.");
        }
        else
        {
            log.info("Could not find this achievement.");
        }
};
1 Like 1 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.