Considerations when implementing JSSP projects

General JavaScript programming considerations

Working with XMLHTTP (XHR) Requests

XMLHttpRequest is how you make internet outbound requests to interact with 3rd party APIs. The complete JS XMLHttpRequest specification is located at XMLHttpRequest standard. Review the bullets below for specific considerations and notes about the use of XHR in JSSP.

Data Types considerations

Uploading Files

If you need to upload files, use the following code snippets as a starting point.

Copy

Simple File Upload

//sample simple file upload function using DropBox API
//https://www.dropbox.com/developers/documentation/http/documentation#files-upload
function executeUploadFileMethod(parameters, properties) {
    var path = "/Folder1/" + properties["file1"].filename;
    var accessToken = "eI5X8aj8zHAAAAAAAAAKcuhoKD3hJt6l8bX1htoyST9dtvGVuj_WxbdkMtEfrQHF";
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status !== 200) throw new Error(xhr.response);
        postResult({
            "result": "File uploaded successfully"
        });
    };
    xhr.open("POST", 'https://content.dropboxapi.com/2/files/upload');
    xhr.setRequestHeader("Authorization", "Bearer " + accessToken);
    xhr.setRequestHeader("Content-Type", "application/octet-stream");
    xhr.setRequestHeader("Dropbox-API-Arg", '{"path": "' + path + '"}');
    xhr.send(properties["file1"]);
}
Copy

Session File Upload

//sample session file upload function using Google Drive API
//https://developers.google.com/drive/api/v3/manage-uploads
function executeUploadFileMethod(parameters, properties) {
    var metadata = {
        "name": properties["file1"].filename
    };
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status !== 200) throw new Error(xhr.response);
        var uploadUrl = xhr.getResponseHeader("Location");
        var xhr2 = new XMLHttpRequest();
        xhr2.onreadystatechange = function () {
            if (xhr2.readyState !== 4) return;
            if (xhr2.status !== 200) throw new Error(xhr2.response);
            postResult({
                "result": "File uploaded successfully"
            });
        };
        xhr2.open("PUT", uploadUrl);
        xhr2.responseType = "json";
        xhr2.setRequestHeader("Content-Type", "text/plain");
        xhr2.setRequestHeader("Authorization", "Bearer ya29.a0Adw1xeXn6e1pyCzcOOtHxRvRgVmqpJxiv2H-hrCn1ZlKdP1eAUp-64WAncgNgGyeupzs9EP7NyRp0onfiVgaubbZUKqlFjDfgNON_Hj1CRJVwD7n8B2aU4O7PpBjByY2SunthMKO0nnYSD1iMhC5RXgx_3ypSn_Tnus");
        xhr2.send(properties["file1"]);
    };
    xhr.open("POST", 'https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable');
    xhr.responseType = "json";
    xhr.setRequestHeader("X-Upload-Content-Type", "text/plain");
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.setRequestHeader("Authorization", "Bearer ya29.a0Adw1xeXn6e1pyCzcOOtHxRvRgVmqpJxiv2H-hrCn1ZlKdP1eAUp-64WAncgNgGyeupzs9EP7NyRp0onfiVgaubbZUKqlFjDfgNON_Hj1CRJVwD7n8B2aU4O7PpBjByY2SunthMKO0nnYSD1iMhC5RXgx_3ypSn_Tnus");
    xhr.send(JSON.stringify(metadata));
}
Copy

Multi-part Form Data File Upload

//sample Multi-part Form Data file upload function using Box API
function executeUploadFileMethod(parameters, properties) {
    var oauthToken = "o954JTWP4IFkdSEIQbK2uIhH558i58XB";
    var form = new FormData();
    form.append('attributes', JSON.stringify({
        "name": properties["file1"].filename,
        "parent": {
            "id": "0"
        }
    })); //IMPORTANT
    form.append('file', properties["file1"].content);
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status !== 201) throw new Error("Failed with status " + JSON.stringify(xhr.response));
        postResult({
            "result": "File uploaded successfully" + JSON.stringify(xhr.response)
        });
    };
    xhr.open("POST", 'https://upload.box.com/api/2.0/files/content', true);
    xhr.setRequestHeader('Authorization', 'Bearer ' + oauthToken);
    xhr.send(form);
}

About the Chakra Engine

The JSSP uses the Microsoft Chakra engine for JavaScript execution, which runs as a service in the environment. It is important to know that for the engine to do anything, that you must enable it with the appropriate interfaces.

The Chakra core is enabled only for XHR to make web requests, communicate with the K2 SmartObject APIs, use cached K2 OAuth tokens, and log console methods. If you try to include dependencies that rely on other common, browser-based functionality such as local disk, temporary storage, or network access, those methods will fail. The engine for the JSSP includes a small subset of what JavaScript developers can use in the context of a web browser, so keep that in mind as you're planning your JS broker projects

There are many technical and business reasons why K2 uses the Microsoft Chakra engine and not the Google V8 engine. These reasons are not covered in this section but know that K2 has a mechanism to update the engine when Microsoft releases updates and will respond within the appropriate timeframe given the nature of the updates (tuning, bug fixing, security vulnerability fix, etc.).

The Chakra engine used in K2 does not have the same functionality as a JavaScript engine in a web browser or the Google V8 engine. You will not be able to directly use Node.js modules since the Chakra engine does not run on the V8 engine. If you need to use a Node.js module, see if you can use a polyfill approach or use browserify to bundle dependencies.