Documentation

Did you find this helpful?

ES6 Features in Cloud Script

Cloud Script runtime environment supports most of modern ECMAScript 6 features. While majority of those are syntactical tricks, one can use them to improve and clean Cloud Script code base.

Complete overview of ES6 features is available in this Cheat Sheet. This guide shows several tricks you may use in your Cloud Script.

Note: Some of the features require `strict` mode. Enable it by placing the following snippet as the very first line of your Cloud Script file:

'use strict';

String interpolation

When composing messages for your players, you might want to use multi-line interpolated strings. Use back-tick symbol to create interpolated String. You may then insert data right into the string using '${ variable }' syntax. This allows you to avoid string concatenation and improve code readability significantly. Back-tick strings are verbatim and may be multi-line. This means you have to keep an eye on all indention as any extra space/tab will be captured into the string:

function sendPushNotification(playerName, prizeAmount, newLevel) {
    let message = `Congratulations ${playerName}! 
You have reached level ${newLevel}.
You get ${prizeAmount} coins for your efforts.`;
    // Use message variable and send push notification
    // ...
}

New methods and arrow functions

ES6 brings new syntax for defining functions using arrow operator '=>'.  The following snippet shows approximate translations for certain operator usages:

// The following snippets:
let add = (a,b) => a+b;

let add = (a,b) => {
    return a+b;
}

// Both translate into something like
function add(a, b) {
    return a+b;
}

This operator combined with new 'Array.findIndex' method allows searching by predicate with the following well-looking, succinct code:

let players = [...]; // Suppose this is an array of Player Profiles

// Search by predicate: find item in 'players' that has 'DisplayName' set to 'Bob':
let bobIndex = players.findIndex(p => p.DisplayName === 'Bob');

Object assignment

'Object.assign' method allows you to easily extend any object with a new set of properties and methods. Having a large variety of usages, this method is particularly useful for extending 'handlers' object and creating 'groups of handlers':

let TestHandlers = {
    TestLeaderboards : (args, ctx) => {
        // Test leaderboards code
    },
    TestPrizes : (args, ctx) => {
        // Test prizes code
    }
    // ...
}

let ProductionHandlers = {
    CleanUp : (args, ctx) => {
        // System clean up code
    },
    GrantTournamentAccess : (args, ctx) => {
        // Another useful production code
    }
    // ...
}

// Install both handler groups:
Object.assign(handlers, TestHandlers);
Object.assign(handlers, ProductionHandlers);

// Comment out the group to disable it but keep the relevant code
// Object.assign(handlers, SomeOtherHandlers);

This not only allows you to quickly enable and disable handler groups, but also it gives you a point to process your handlers and wrap them with useful code, such as exception handling. The following code extends the previous snippet with automatic exception logging. As an example, we log the problem, which is not always useful, but you can extend the behavior to your taste:

// Handlers installer wraps the handler to catch error 
function installHandlers(handlersObject) {
    for (var property in handlersObject) {
        handlersObject[property] = wrapHandler(handlersObject,property)
    }
    Object.assign(handlers, handlersObject);
}

// Utility
function wrapHandler(obj, key) {
    if (obj.hasOwnProperty(key) && typeof obj[key] === 'function') {
        var original = obj[key]; // Take the original function
        return function() { // return a new function that
            try { // Wraps the original invocation with try
                return original.apply(null,arguments); // Do not forget to pass arguments
            } catch (error) { // If error occurs
                log.error(error); // We log it, but you may want to retry / do something else
                throw error; // Rethrow to keep the original behaviour
            }
        } 
    } else { // If property is not a function, ignore it
        return obj[key];
    }
}

// Install handler groups:
installHandlers(TestHandlers);
installHandlers(ProductionHandlers);

Getters

One may use getters to encapsulate common API calls into a more syntactically pleasing look and feel. Consider the following TitleData state:

The following snippet shows how to retrieve 'Foo' and 'Bar' data from TitleData and then use in a very straightforward way. 

'use strict'

// Define
let App = {
    get TitleData() {
        // Please, consider limiting the query by defining certain keys that you need
        return server.GetTitleData({}).Data;
    },
}

// Use
handlers.TestFooBar = () => {
    // Client code is clean and does not show the fact of calling any functions / making api request
    var titleData = App.TitleData; // Note that this implementation makes an API call every time it's accessed
    log.debug(titleData.Foo);
    log.debug(titleData.Bar);
}



Did you find this helpful?