TotalTechGeek / json-logic-engine

Construct complex rules with JSON & process them.
MIT License
43 stars 9 forks source link

Can't get json-logic-engine to work with this logic #20

Closed boozedog closed 1 month ago

boozedog commented 8 months ago

Hi there! I am evaluating json-logic-engine and I am finding that the following logic compiles but crashes at runtime. Same rule/data works in json-logic-js.

Logic:

{
    "map": [
        {
            "var": ""
        },
        {
            "*": {
                "cat": [
                    {
                        "var": "a"
                    },
                    " ",
                    {
                        "var": "b"
                    }
                ]
            }
        }
    ]
}

Data:

[
    {
        "a": "foo",
        "b": "bar"
    },
    {
        "a": "fizz",
        "b": "buzz"
    }
]

Error:

Uncaught TypeError: ("" + ((intermediate value) ?? null) + " " + ((intermediate value) ?? null)).reduce is not a function
TotalTechGeek commented 8 months ago

I'm not entirely sure that this should be considered valid logic; I'm tempted to put some work in to make the error message better (and not crash it at runtime), but the logic is essentially asking:

multiply("foo bar")

Multiplying with one argument, where that argument is a string.

Is the expectation here that if multiply receives a single operand, it just returns the same value, with the same type? I'm not sure if I want to make that the default behavior, but if that is indeed your need, you can do this:

engine.addMethod('*', (data) => Array.isArray(data) ? data.reduce((a, b) => +a * +b) : data, { deterministic: true })

This can be used to override the behavior.

I can be convinced though!

boozedog commented 8 months ago

Ahh thanks @TotalTechGeek ! I am new to JsonLogic ... that was definitely a mistake in my logic. I was just trying to return some strings as part of my learning process. Here's the corrected json:

{
    "map": [
        {
            "var": ""
        },
        {
            "cat": [
                {
                    "var": "a"
                },
                " ",
                {
                    "var": "b"
                }
            ]
        }
    ]
}

which returns the expected output: ["foo bar","fizz buzz"]

I agree that a better error message would be helpful, but on the other hand json-logic-js executes it with no error at all which seems worse to me!

Thanks for your help

TotalTechGeek commented 8 months ago

If you have any other questions, please don't hesitate to drop a comment!

I'm going to leave this issue open to look into improving the error messages / validation.