How to find failed facts from json rule engine - javascript

I am new to the rules engine and I am trying to create a rules engine in javascript.
I have the following rule and Passing one parameter as the wrong input, how to find which argument (fact) is mismatched (not the rule).
engine.addRule({
conditions: {
all: [{
fact: 'score',
operator: 'greaterThanInclusive',
value: 200
}, {
fact: 'players',
operator: 'equal',
value: 10
}]
},
event: {
type: 'success',
}
})
let fact = {
score: 150,
players: 10
}
It will fail the rule. How do I know which fact cause the failure of rule?

We gives a property event which will fired when rules match . If rules match the length of events going to be greater than 0.
Example:
const { events } = await engine.run(facts);
if (events.length > 0) {
return true
}
In the case of failure of rule events length going to be zero.

Related

Write assertion subject to whether key has value

I'm trying to come up with a method that would allow me to create a it block that confirms whether my configuration file has a specific attribute. The object has in it:
exports.config = {
services: [
['sauce', {
sauceConnect: true,
}]
],
}
I would like to have an it block that would confirm whether this value is true and if it isn't, then it should fail.
I have tried a couple approaches like if (sauceConnect in services) etc but it isn't an approach that is working. The test and the configuration file are in separated documents and for the life of me I can't work out a good enough test.
I'd appreciate any help or answers here.
On the assumption that this is how you want your config to look like, you'll have to loop through it and find the match:
const exportedConfig = {
services: [
['sauce', {
sauceConnect: true,
}],
['key', {
data: "value",
}]
],
}
// [1] refers to the 2nd element in the array, aka the value
// some looks for ANY match and if a match occurs it returns true.
console.log(exportedConfig.services.some(element => element[1].sauceConnect == true ))
Though, a recommendation would be to format your config as so:
const exportedConfig = {
services: {
sauce: {
sauceConnect: true,
},
key: {
data: "value",
}
},
}
``

Accessing Hierarchy Data in an Object Javascript

I need to access the id value in a Javascript object to display a simple message that the user has membership if the id value equals a specific value.
I'm getting Uncaught Type Error not defined 'id' message
In the console it's displayed as
subscriptions: Array(1)
0: // COMMENT Don't know what this is
autoRenew: false
canRenew: false
expiryDate: "2022-10-26T00:00:00"
membership:
id: "819AGBHDRLQHNHPHKKMPKLGPMDRDTDMVL"
I'm assuming equivalent JSON is something like:
subscriptions {
0
{
membership: {
id: "819AGBHDRLQHNHPHKKMPKLGPMDRDTDMVL"
}
}
}
My Javascript Code
const userObj3 = userObj['subscriptions']['0']['membership']['id'];
if (userObj3 = "819AGBHDRLQHNHPHKKMPKLGPMDRDTDMVL") {
greeting = "You have membership";
}
Your subscriptions are an array, also your comparison inside the if is incorrect and should be == or ===, you could also use dot annotation to traverse the object instead of using brackets on every key.
Using the index as a string instead of a number isn't really wrong, it's just not a good practice.
You might want to think about looping through the subscriptions instead of using the direct index just in case there's multiple subscriptions. But that just depends on how you structure your data and is kinda up to you.
const userObj = {
subscriptions: [
{
autoRenew: false,
canRenew: false,
expiryDate: '2022-10-26T00:00:00',
membership: {
id: '819AGBHDRLQHNHPHKKMPKLGPMDRDTDMVL'
}
},
{
autoRenew: true,
canRenew: false,
expiryDate: '2022-10-26T00:00:00',
membership: {
id: '201AGBHDRLQHNHPHKKMPKLGPMDRDTDMVL'
}
}
]
};
let greeting = "You're not a member";
userObj.subscriptions.forEach((sub) => {
if (sub.membership.id === '201AGBHDRLQHNHPHKKMPKLGPMDRDTDMVL') {
greeting = "You're a member";
}
});
console.log(greeting);

TypeError: Cannot read property 'time' of undefined

I have type error. My variable creating this error while running with node.js. My variable is below. How can I describe my variable correctly ?
let allDevices = {
1: {
time: []
},
2: {
time: []
},
3: {
time: []
}
}
I'm guessing you're trying allDevices.1.time to get the above error message. With numeric object keys, you'd need to reference the numbered object keys using [] instead of . notation:
let allDevices = {
1: {
time: []
},
2: {
time: []
},
3: {
time: []
}
}
console.log(allDevices[1].time) // or allDevices['1'].time
You probably don't want that object structure, though; allDevices should probably just be an array, so you don't need to manage the index numbers manually. You'd access it the same way (but note that arrays are zero-indexed):
let allDevices = [
{
time: []
},
{
time: []
},
{
time: []
}
]
console.log(allDevices[0].time) // here, allDevices['1'] would not work; the index must be a number
If you are using the bracket notation already but still getting 'undefined' errors, check to make sure the data exists before you try accessing it; if allDevices is set up by something asynchronous you'll need to wait until that async call returns.

How to search nested object by following JSLint

I have my object structured as below and I want to find the product with provided ID.
0 :{
id: 0,
title: 'xxxx',
url: "www.test.com"
quantity: 100
},
1 :{
id: 10,
title: 'xxxx',
url: "www.test.com"
quantity: 100
},
// and so on...
In order to search nested attribute within the object, I have written the below function:
export const selectProductById = (state, productId) => {
const obj_index = Object.keys(state.products).find(function(idx) {
if (state.products[idx].id == productId) {
return idx;
}
}
return state.products[obj_index]
}
This works but I will always get a warning during compilation of my react app.
Expected '===' and instead saw '=='
But if I change this into === the code will not work anymore, does anyone knows how to change this so that it follows JSLint rules ?
It sounds like the productId is not a number. Cast it to a number first:
if (state.products[idx].id === Number(productId)) {
But you should return a truthy or falsey value from the .find callback, not something that you're iterating over (since you may not be sure whether it's truthy or falsey, and it's potentially confusing). Return the result of the === comparison instead:
const { products } = state;
const obj_index = Object.keys(products).find(
key => products[key].id === Number(productId)
);

Distinguish methods and properties

The Problem:
I'm currently improving the valid-expect rule for the eslint-plugin-jasmine package trying to handle one more invalid Jasmine expect() usage when a matcher is not called:
expect(true).toBeDefined;
Valid usage:
expect(true).toBeDefined();
I'm getting pretty close - I can determine that there is a member expression on the expect():
// matcher was not called
MemberExpression: function (node) {
if (node.object && node.object.callee.name === 'expect') {
console.log(node.property)
}
}
But the node.property in both valid and invalid cases is of an Identifier type:
Node {
type: 'Identifier',
start: 13,
end: 24,
loc:
SourceLocation {
start: Position { line: 1, column: 13 },
end: Position { line: 1, column: 24 } },
range: [ 13, 24 ],
name: 'toBeDefined' }
And there is nothing obvious indicating that this is a property or a method.
The Question:
How can I determine if a property is callable or not in ESLint?
expect(true).toBeDefined is parsed into a MemberExpression node, but expect(true).toBeDefined() is parser into a CallExpression. I'm not really 100% sure why this is happening, but in the second case, it seems to think that the whole statement up until opening brackets is one single CallExpression, I would expect there to be two separate CallExpression, but that doesn't seems to be the case.
So what you can do is listen to CallExpression and check that callee is Identifier with name expect. And then check if it's grandparent is a MemberExpression or another CallExpression.

Categories

Resources