Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not possible to use 0 in if/or/and? #94

Open
dextervanroo opened this issue Jan 8, 2021 · 6 comments
Open

Not possible to use 0 in if/or/and? #94

dextervanroo opened this issue Jan 8, 2021 · 6 comments

Comments

@dextervanroo
Copy link

dextervanroo commented Jan 8, 2021

Hello. I'm trying to write a code for a data interval check and I was having trouble at first with the nested-if logic. After reading #69 I think got it right. What I'm trying to do is the following:

  1. if data.km or km is false, return erro1
  2. elif 0 <= data.km or km <= 2.352, return aqui
  3. elif 4.916 <= data.km or km <= 16.846, return embaixo
  4. else return errei
{
	"if": [{
		"or": [{
			"===": [{
				"var": "data.km"
			}, false]
		}, {
			"===": [{
				"var": "km"
			}, false]
		}]
	}, "erro1", {
		"or": [{
			"and": [{
				"**>=**": [{
					"var": "data.km"
				}, 0]
			}, {
				"<=": [{
					"var": "data.km"
				}, 2.352]
			}]
		}, {
			"and": [{
				"**>=**": [{
					"var": "km"
				}, 0]
			}, {
				"<=": [{
					"var": "km"
				}, 2.352]
			}]
		}]
	}, "aqui", {
		"or": [{
			"and": [{
				">=": [{
					"var": "data.km"
				}, 4.916]
			}, {
				"<=": [{
					"var": "data.km"
				}, 16.846]
			}]
		}, {
			"and": [{
				">=": [{
					"var": "km"
				}, 4.916]
			}, {
				"<=": [{
					"var": "km"
				}, 16.846]
			}]
		}]
	}, "embaixo", "errei"]
}

The problem is that this logic only works if I remove the = part of the highlighted >=. Am I doing something wrong or is this intended behavior?

@shupoval
Copy link

@dextervanroo, in case this issue is still something that you are struggling with, could you please provide an example of a data object that you are using in your tests that causes this issue. I've performed a few quick tests and it looks like that everything works as expected. I suspect this is due to the data object that I'm using for my tests.

@dextervanroo
Copy link
Author

@shupoval If I use {"km":10} in the data test, it should return embaixo, but it returns aqui. If I remove the = part in the highlighted terms, it correctly returns embaixo.

@shupoval
Copy link

@dextervanroo, thank you for the clarification. It is clear now.

The long story short, in case {"var": "data.km"} and data.km is not defined, JsonLogic's var operator defaults it to the null value (if no default value was specified in the logic's expression). Btw, it is possible to specify default value by using the following syntax {"var": ["data.km", DEFAULT_VALUE_GOES_HERE]}. After that JavaScript's NULL Comparison takes place and this is true for all comparison operators (not only >= or <=).

@jwadhams, shouldn't we come up with something similar to the Truthy and Falsy in case of comparison operators in order to make JsonLogic's rules return the same results when executed by different languages?

@dextervanroo, I'd like to suggest you to switch from the {"var": "SOME_DATA_PATH"} to the {"var": ["SOME_DATA_PATH", DEFAULT_VALUE_GOES_HERE]} syntax in order to have consitant and predictable results in case of undefined/missed data represented by "SOME_DATA_PATH" reference.

@shupoval
Copy link

Seems like this issue is related to #44 and #60

@dextervanroo
Copy link
Author

dextervanroo commented Mar 26, 2021

@shupoval But why is it that the code works just by removing the = signs, like this:

{
	"if": [{
		"or": [{
			"===": [{
				"var": "data.km"
			}, false]
		}, {
			"===": [{
				"var": "km"
			}, false]
		}]
	}, "erro1", {
		"or": [{
			"and": [{
				"**>=**": [{
					"var": "data.km"
				}, 0]
			}, {
				"<=": [{
					"var": "data.km"
				}, 2.352]
			}]
		}, {
			"and": [{
				"**>=**": [{
					"var": "km"
				}, 0]
			}, {
				"<=": [{
					"var": "km"
				}, 2.352]
			}]
		}]
	}, "aqui", {
		"or": [{
			"and": [{
				">=": [{
					"var": "data.km"
				}, 4.916]
			}, {
				"<=": [{
					"var": "data.km"
				}, 16.846]
			}]
		}, {
			"and": [{
				">=": [{
					"var": "km"
				}, 4.916]
			}, {
				"<=": [{
					"var": "km"
				}, 16.846]
			}]
		}]
	}, "embaixo", "errei"]
}

Same test parameter ({"km":10})

@shupoval
Copy link

@dextervanroo, the reason is due to how javascript evaluates NULL comparison:

  • null > 0 evaluates into false
  • null >= 0 evaluates into true

In your case when data is {"km":10} which means {"var": "data.km"} evaluates into null and that is why the second if evaluetes into true and "aqui" string is printed out due to the following expression:

if((null >= 0 && null <= 2.352) || (10 >= 0 && 10 <= 2.352)) 
    console.log("aqui");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants