grule-rule-engine icon indicating copy to clipboard operation
grule-rule-engine copied to clipboard

Map Key Does Not Exist - Errors - How to write such rules with maps?

Open alok87 opened this issue 1 year ago • 2 comments

Fact

fact := &Fact{
		ItemCount:     5,
		SkuCount:      3,
		CategoryCount: 3,
		CatList:       []string{"cat1,cat2,cat3"},
		SkuList:       "sku1,sku2,sku3",
		Category: map[string]fact.Category{
			"cat1": {
				ItemCount: 5,
				SkuCount:  3,
			},
		},
		Skus: map[string]fact.Sku{
			"sku1": {
				ItemCount:    5,
				VariantCount: 3,
			},
		},
	}

Rule

Fact.Category["cat2"].ItemCount > 5

This errors saying "cat2" does not exist in Category. How do you write such rules?

alok87 avatar Jul 21 '23 20:07 alok87

Custom functions works!

Rule:

When:     "Magic.CategoryItemCount("cat2") > 3",

Custom Function works

func (m Magic) CategoryItemCount(category string) int {
	if _, ok := m.Category[category]; !ok {
		return -1
	}
	return m.Category[category].ItemCount
}

alok87 avatar Jul 22 '23 04:07 alok87

There's a small mistake in your provided example - you populate the Category map with a key cat1 but appear to be checking for cat2 in your rule.

Regardless, this should work. You can access properties on structs in maps as expected. One key note is that this does not work for maps to interfaces! i.e. map[string]fact.Category is fine, but map[string]interface{} is not. However map[string]interface{} will work for basic types (int64 / string / bool / float64).

Simple things to check:

  • that your keys do match
  • you are using the correct name for your fact (as it was added to the DataContext)

OvenBaker avatar Jul 24 '23 11:07 OvenBaker