Skip to content

Commit a62d1ee

Browse files
author
Cache Hamm
committed
add fact-comparison example
1 parent ac38086 commit a62d1ee

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

examples/08-fact-comparison.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
'use strict'
2+
3+
/*
4+
* This is a basic example demonstrating a condition that compares two facts
5+
*
6+
* Usage:
7+
* node ./examples/08-fact-comparison.js
8+
*
9+
* For detailed output:
10+
* DEBUG=json-rules-engine node ./examples/08-fact-comparison.js
11+
*/
12+
13+
require('colors')
14+
let Engine = require('../dist').Engine
15+
16+
/**
17+
* Setup a new engine
18+
*/
19+
let engine = new Engine()
20+
21+
/**
22+
* Rule for determining if account has enough money to purchase a $50 gift card product
23+
*
24+
* customerAccount (in euros) >= $50 gift card
25+
*/
26+
let rule = {
27+
conditions: {
28+
all: [{
29+
// extract 'balance' from the 'customer' account type
30+
fact: 'account',
31+
path: '.balance',
32+
params: {
33+
accountType: 'customer'
34+
},
35+
36+
operator: 'greaterThanInclusive', // >=
37+
38+
// "value" in this instance is an object containing a fact definition
39+
// fact helpers "path" and "params" are supported here as well
40+
value: {
41+
fact: 'product',
42+
path: '.price',
43+
params: {
44+
productId: 'giftCard'
45+
}
46+
}
47+
}]
48+
},
49+
event: { type: 'customer-can-afford-gift-card' }
50+
}
51+
engine.addRule(rule)
52+
53+
engine.addFact('account', (params, almanac) => {
54+
// get account list
55+
return almanac.factValue('accounts')
56+
.then(accounts => {
57+
// use "params" to filter down to the type specified, in this case the "customer" account
58+
let customerAccount = accounts.filter(account => account.type === params.accountType)
59+
// return the customerAccount object, which "path" will use to pull the "balance" property
60+
return customerAccount[0]
61+
})
62+
})
63+
64+
engine.addFact('product', (params, almanac) => {
65+
// get product list
66+
return almanac.factValue('products')
67+
.then(products => {
68+
// use "params" to filter down to the product specified, in this case the "giftCard" product
69+
let product = products.filter(product => product.productId === params.productId)
70+
// return the product object, which "path" will use to pull the "price" property
71+
return product[0]
72+
})
73+
})
74+
75+
/**
76+
* Register listeners with the engine for rule success and failure
77+
*/
78+
let facts
79+
engine
80+
.on('success', (event, almanac) => {
81+
console.log(facts.userId + ' DID '.green + 'meet conditions for the ' + event.type.underline + ' rule.')
82+
})
83+
.on('failure', rule => {
84+
console.log(facts.userId + ' did ' + 'NOT'.red + ' meet conditions for the ' + rule.event.type.underline + ' rule.')
85+
})
86+
87+
// define fact(s) known at runtime
88+
let productList = {
89+
products: [
90+
{
91+
productId: 'giftCard',
92+
price: 50
93+
}, {
94+
productId: 'widget',
95+
price: 45
96+
}, {
97+
productId: 'widget-plus',
98+
price: 800
99+
}
100+
]
101+
}
102+
103+
let userFacts = {
104+
userId: 'washington',
105+
accounts: [{
106+
type: 'customer',
107+
balance: 500
108+
}, {
109+
type: 'partner',
110+
balance: 0
111+
}]
112+
}
113+
114+
// compile facts to be fed to the engine
115+
facts = Object.assign({}, userFacts, productList)
116+
117+
engine
118+
.run(facts) // first run, user can afford a gift card
119+
.then(() => {
120+
// second run; a user that cannot afford a gift card
121+
userFacts = {
122+
userId: 'jefferson',
123+
accounts: [{
124+
type: 'customer',
125+
balance: 30
126+
}]
127+
}
128+
facts = Object.assign({}, userFacts, productList)
129+
return engine.run(facts)
130+
})
131+
.catch(console.log)
132+
133+
/*
134+
* OUTPUT:
135+
*
136+
* washington DID meet conditions for the customer-can-afford-gift-card rule.
137+
* jefferson did NOT meet conditions for the customer-can-afford-gift-card rule.
138+
*/

0 commit comments

Comments
 (0)