Skip to content
Jeremy Wadhams edited this page Jul 14, 2017 · 5 revisions

It's not always practical to add a top-level baked-in method for every possible use case—that's how you end up with PHP. 🙃

But it is possible to build hugely powerful custom methods, and the community has created lots of them. This Wiki is a place to show off, or to link out to larger libraries or longer blog-length discussions.

Temporary Variables

Sometimes, you need some scratch space to re-use a result more than once in your rule. The core JsonLogic implementation has no setters, which helps developers trust customer-provided rules. These operations break that tenet, but in a relatively safe, sandboxed way:

jsonLogic.add_operation("set_temp", function(key, value){
    if( ! this.temp_variables){ this.temp_variables = {}; }
    this.temp_variables[key] = value;
    return value;
});

jsonLogic.add_operation("get_temp", function(key){
    if( ! this.temp_variables){ this.temp_variables = {}; }
    return this.temp_variables[key];
});

Example

This rule tests that a complicated regex matches, and that an optional capture group is empty. (Note, it uses an implementation of index found below)

var rule = {"and":[
    {'!=':[
        null,
        {"set_temp":[
            "match_result",
            {"method":[
                {"var":"a"},
                "match",
                ["(.)(.)(.)?(.)"]
            ]}
        ]}
    ]},
    {"==":[
        null,
        {"index":[
            {"get_temp":"match_result"},
            3
        ]}
    ]}
]};

jsonLogic.apply(rule, {"a": "ab"}); //false, match fails
jsonLogic.apply(rule, {"a": "abc"}); //true, match succeeds, optional capture missing
jsonLogic.apply(rule, {"a": "abcd"}); //false, match succeeds, optional capture present

Working with Intermediate Arrays

The var operation supports getting array elements and object properties, but that's only helpful on things stored in the data object. What can we do for arrays and objects created in our code?

One crazy powerful solution would be to use the excellent Dotty library which would also get you setters, search, and deep index lookup:

var jsonLogic = require('json-logic-js');

jsonLogic.add_operation('dotty', require('dotty') );
var rule = {"dotty.get":[
    {"merge":[
        {"var":"actors"},
        {"var":"models"}
    ]},
    "0"
]};
var data = {"actors":["David Duchovny"], "models":["Derek Zoolander", "Hansel"]};

jsonLogic.apply(rule, data); //"David Duchovny"

You could also just write your own very very simple implementation (like we use in the temp variables example) like:

jsonLogic.add_operation("index", function(a, b){
    if(typeof a === 'undefined' || a === null){
        return undefined;
    }
    return a[b];
});