Basic Application [Node.js]

This example is the same as the Browser Basic Application example except run through a node server.

There is a decision shape that calls itself until the value data.a > 10 at which point it terminates and calls the complete function.

Download »

Setup

App.js contains all the functions that the decision tree will use to manipulate the object

Json.js contains a JSON object for the root shape

To run it download the code, open a console and type node server.js

Object to Process

We create a new object to process. This object is passed to the decision tree and is altered by the functions in the tree.

Any functions processing the object should be aware of it's structure or handle incorrect objects by throwing an error.

//create a data object to process
        var data = { "a": 1 };

Root Shape

Every decision tree requires a root shape to start processing at. This example has it stored in the json.js file.

The process and decision functions in the shape are set using processName and decideName and are referencing functions in the TestApp e.g. "processName": "TestApp.add" and "decideName": "TestApp.checkValue"

var shape = exports.shape = {
    "shapeType": "Entry",
    "id": 1,
    "description": "Start",
    "nextShape": {
        "shapeType": "Operation",
        "id": 2,
        "description": "Adding value 2",
        "nextShape": {
            "shapeType": "Decision",
            "id": 3,
            "description": "Adding value 2",
            "paths": [{
                "value": true,
                "selected": false,
                "nextShape": null,
                "nextShapeId": 3
            },
            {
                "value": false,
                "selected": false,
                "nextShape":
                    {
                        "shapeType": "Operation",
                        "id": 5,
                        "description": "Adding nothing",
                        "nextShape": null,
                        "properties": { "value": 0 },
                        "processName": "TestApp.add"
                    },
                "nextShapeId": 0
            }],
            "properties": { "value": 2, "decision": 10 },
            "processName": "TestApp.add",
            "nextShape": null,
            "decideName": "TestApp.checkValue"
        },
        "properties": { "value": 2 },
        "processName": "TestApp.add"
    }
};
                    
                

Run Test

The TestApp is added to the decisionTree.execute function along with the standed options of the root shape, the data object to process and sets a callback function to be called on complete.

For more information on sending apps to the execute function check out the documentation


//execute the tree on the root shape
decisionTree.execute(tree.shape, data, TestApp.complete, { "TestApp": TestApp });
var TestApp = require("./app.js");
var tree = require("./json.js");
var decisionTree = require("./decisionTree.min.js");

//create a data object to process
var data = { "a": 1 };

//execute the tree on the root shape
decisionTree.execute(tree.shape, data, TestApp.complete, { "TestApp": TestApp });
                    
                
var TestApp = exports;
(function (TestApp) {
    //logs messages to the console
    TestApp.log = function (message) {
        console.log(message);
    };
    //add function
    function add(data, shape, callback) {
        try {
            TestApp.log("*************");
            TestApp.log("add function called");
            TestApp.log("data.a=" + data.a);
            var v = Number(shape.properties.value);
            if(isNaN(v)) {
                throw new Error("'" + v + "' is not a number");
            }
            TestApp.log("adding: " + v);
            data.a += v;
            TestApp.log("data.a=" + data.a);
            callback(null, shape);
        } catch (e) {
            callback(e, shape);
        }
    }
    TestApp.add = add;
    //check value function
    function checkValue(data, shape, callback) {
        try  {
            TestApp.log("*************");
            TestApp.log("checkValue function called");
            TestApp.log("checking data.a (" + data.a + ") is less than shape.properties.decision (" + shape.properties.decision + ")");
            if(data.a < shape.properties.decision) {
                TestApp.log("data.a < shape.properties.decision selecting path[0]");
                shape.paths[0].selected = true;
                shape.paths[1].selected = false;
            } else {
                TestApp.log("data.a >= shape.properties.decision selecting path[1]");
                shape.paths[0].selected = false;
                shape.paths[1].selected = true;
            }
            callback(null, shape);
        } catch (e) {
            callback(e, shape);
        }
    }
    TestApp.checkValue = checkValue;
    //complete function
    function complete(err, result, processedShapes) {
        TestApp.log("*************");
        TestApp.log("complete function called");
        TestApp.log("error: " + err);
        TestApp.log("result: " + result.a);
        for(var x = 0; x < processedShapes.length; x++) {
            TestApp.log("processed Shape: " + processedShapes[x].description + " id:" + processedShapes[x].id);
        }
        TestApp.log("Processed shapes JSON");
        //TestApp.log(JSON.stringify(processedShapes));
    }
    TestApp.complete = complete;
})(TestApp || (TestApp = {}));

                    
                
var shape = exports.shape = {
    "shapeType": "Entry",
    "id": 1,
    "description": "Start",
    "nextShape": {
        "shapeType": "Operation",
        "id": 2,
        "description": "Adding value 2",
        "nextShape": {
            "shapeType": "Decision",
            "id": 3,
            "description": "Adding value 2",
            "paths": [{
                "value": true,
                "selected": false,
                "nextShape": null,
                "nextShapeId": 3
            },
            {
                "value": false,
                "selected": false,
                "nextShape":
                    {
                        "shapeType": "Operation",
                        "id": 5,
                        "description": "Adding nothing",
                        "nextShape": null,
                        "properties": { "value": 0 },
                        "processName": "TestApp.add"
                    },
                "nextShapeId": 0
            }],
            "properties": { "value": 2, "decision": 10 },
            "processName": "TestApp.add",
            "nextShape": null,
            "decideName": "TestApp.checkValue"
        },
        "properties": { "value": 2 },
        "processName": "TestApp.add"
    }
};