Skip to content

Converting older (JSON) rulesets to JayRule format

JayRule provides a much more straightforward language and structure for defining rules than the older style (Javascript/JSON), which was quite prone to error and crashing.

Switching from a regular JSON ruleset is fairly straightforward.

For non-asynchronous rules

JSON Normal layout of a rule block (non-asynchronous)


// ----------------------------------------------------
// Rule "ABC"
// ----------------------------------------------------
if (
    !ntf.hasRun.ruleABC
    && condition
) {
    ntf.logger.info('In rule "ABC");
    action
    ntf.hasRun.ruleABC = true;
}


to JayRule ruleblock (non-asynchronous):


// ----------------------------------------------------
// Rule "ABC"
// ----------------------------------------------------
ruleABC : {
    ruleCondition : function(ntf) {
        return (condition);
    },

    ruleAction : function(ntf) {
        action
    }
}


Note, the ntf.hasRun.flag does not need to be set, nor does the logger line for the rule starting.

Eg

// ----------------------------------------------------  
// Rule "ABC"  
// ----------------------------------------------------  
if (  
    !ntf.hasRun.ruleABC  
    && ntf.context.fieldChanged = 'buttonABC'  
) {  
    ntf.hasRun.ruleABC = true;  
    ntf.logger.info('In rule "ABC");  
    ft3.ModalService.openModal('ABC', 'Hello from the ABC button'), 'info');  
    ntf.document.abcClicker = ntf.user.email;
}  

converts to

// ----------------------------------------------------  
// Rule "ABC"  
// ----------------------------------------------------  
ruleABC : {  
    ruleCondition : function(ntf) {  
        return (ntf.context.fieldChanged === 'buttonABC');  
    },  

    ruleAction : function(ntf) {  
        var ft3 = ntf.scope;
        ft3.ModalService.openModal('ABC', 'Hello from the ABC button'), 'info');  
        ntf.document.abcClicker = ntf.user.email;
    }
}  

For asynchronous rules


// ----------------------------------------------------
// Rule "ABC"
// ----------------------------------------------------
if (
    !ntf.hasRun.ruleABC
    && condition
) {
    ntf.logger.info('In rule "ABC");
    action(..., function(..) {
        ...
        ntf.hasRun.ruleABC = true;
        callbackContinue(ntf);
    });
    return;
}


to JayRule ruleblock (asynchronous):


// ----------------------------------------------------
// Rule "ABC"
// ----------------------------------------------------
ruleABC : {
    ruleCondition : function(ntf) {
        return (condition);
    },

    ruleAction : function(ntf, callback) {
        action(..., function(..) {
            ...
            callback();
        });
    } }


Note, the ntf.hasRun.flag does not need to be set, and return does not need to be added, nor does the logger line for the rule starting.

Eg

// ----------------------------------------------------  
// Rule "ABC"  
// ----------------------------------------------------  
if (  
    !ntf.hasRun.ruleABC  
    && ntf.context.fieldChanged = 'buttonABC'  
) {  
    ntf.hasRun.ruleABC = true;  
    ntf.logger.info('In rule "ABC");  

    var eqry = {"query": {"bool": {"filter": [
        {"term" : {"documentId" : "1234"}}
    ]}}}; 

    ft3.findDocumentsByElastic(eqry, ntf.user.documentId, function(err, result) {
        if (result && result.data && result.data.hits) {
            ft3.showNotification('# documents found: ' + result.data.hits.total);
        }
        callbackContinue(ntf);
        return;
    });
    return;
}  

converts to

// ----------------------------------------------------  
// Rule "ABC"  
// ----------------------------------------------------  
ruleABC : {  
    ruleCondition : function(ntf) {  
        return (ntf.context.fieldChanged === 'buttonABC');  
    },  

    ruleAction : function(ntf, callback) {  
        var ft3 = ntf.scope;
        var eqry = {"query": {"bool": {"filter": [
            {"term" : {"documentId" : "1234"}}
        ]}}}; 

        ft3.findDocumentsByElastic(eqry, ntf.user.documentId, function(err, result) {
            if (result && result.data && result.data.hits) {
                ft3.showNotification('# documents found: ' + result.data.hits.total);
            }
            callback();
        });
    }
}  

Main Caveats

There are a number of things to watch out for in converting from an older JSON script to JayRule format.

Shared Variables

Variables which were defined near top of ruleset, for use by all rules, will need to be defined within an initial rule as properties of ntf and renamed throughout accordingly.

Eg

var isPlanned = (ntf.document.appTags.indexOf('planned') > -1);

would move to within an initialising rule (eg ruleInitialise) and written:

ntf.isPlanned = (ntf.document.appTags.indexOf('planned') > -1);

then all usages of that variable changed to use ntf.isPlanned.

Generally, one can perform a find and replace (Ctrl-H) in the editor, to get all occurrences.

Tip - if you suspect you've performed this too many times, resulting in ntf.ntf.property , run a Find&Replace for "ntf.ntf." to "ntf."

References to main

Functions and other structures declared above the previous mainRule, and now ruleset, are now referenced through ft3.

eg

var custCount = main.getCustomerCount();

must now become

var custCount = ft3.getCustomerCount();

Similarly, functions and/or objects sourced from ruleSetIncludes will now be referenced via ft3 instead.

To check, do a search in the editor for the occurrence of main. There should be no such reference in a JayRule ruleset.

Callbacks

An issue with the old style ruleset too, but double check that all ruleActions that expect a callback, ie

ruleAction : function(ntf, callback) ...

get a callback.

Generally this will come up as a suitably described error on running if the rule does not have a callback defined. Conversely, if one is called within a ruleAction that doesn't expect it, there will also be an error shown.