Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Rule chaining not working with Promise.all

Open
#303 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
javascript
Domain
backend

Research direction

Start by reproducing the Promise.all example in the issue, then inspect Engine.run and the runtime-fact handling used by almanac.addRuntimeFact. Done means the parallel runs produce the corresponding results and events for samuel, joseph, and anthony, matching the sequential behavior.

Written by the indexing model from the issue text.

Description

If I run the engine sequentially, I am getting the desired result. If I run it in parallel, I am getting results only for the first run.

student-fav-subject.js

const { Engine } = require("json-rules-engine");

const apiClient = require("./student-api-client");

let engine = new Engine();

async function start() {
  let mathematicsSubjectRule = {
    conditions: {
      all: [
        {
          fact: "student-information",
          operator: "contains",
          value: "Mathematics",
          path: "$.subjects",
        },
      ],
    },
    event: { type: "studies-mathematics" },
    priority: 10,
    onSuccess: async function (event, almanac) {
      almanac.addRuntimeFact("studiesMathematics", true);
    },
    onFailure: function (event, almanac) {
      almanac.addRuntimeFact("studiesMathematics", false);
    },
  };
  engine.addRule(mathematicsSubjectRule);

  let physicsFavoriteRule = {
    conditions: {
      all: [
        {
          fact: "studiesMathematics",
          operator: "equal",
          value: true,
        },
        {
          fact: "student-information",
          operator: "equal",
          value: "Physics",
          path: "$.favoriteSubject",
        },
      ],
    },
    event: {
      type: "physics-favorite-subject",
      params: {
        message: " has Physics as their favorite subject",
      },
    },
  };

  engine.addRule(physicsFavoriteRule);

  engine.addFact("student-information", function (params, almanac) {
    console.log("loading student information...");
    return almanac.factValue("studentName").then((studentName) => {
      return apiClient.getStudentInformation(studentName);
    });
  });

  engine.on("success", (event, almanac, ruleResult) => {
    almanac.factValue("studentName").then((studentName) => {
      switch (event.type) {
        case "physics-favorite-subject":
          console.log(
            studentName,
            "HAS".green,
            "Physics as their favorite subject"
          );
      }
    });
  });

  engine.on("failure", (event, almanac, ruleResult) => {
    almanac.factValue("studentName").then((studentName) => {
      switch (event.type) {
        case "physics-favorite-subject":
          const studiesMathResult = ruleResult.conditions.all.find(
            (condition) => condition.fact === "studiesMathematics"
          );
          if (studiesMathResult) {
            if (studiesMathResult.result) {
              console.log(
                studentName,
                "DOES NOT".red,
                "have Physics as favorite subject"
              );
            } else {
              console.log(
                studentName,
                "CANNOT NOT".red,
                "have Physics as favorite subject as they do not study Mathematics"
              );
            }
          }
      }
    });
  });

  Promise.all([
    engine.run({ studentName: "samuel" }),
    engine.run({ studentName: "joseph" }),
    engine.run({ studentName: "anthony" }),
  ]);

  // await engine.run({ studentName: "samuel" });
  // await engine.run({ studentName: "joseph" });
  // await engine.run({ studentName: "anthony" });
}

start();

student-api-client.js

"use strict";

require("colors");
const fs = require("fs");

let studentData = require("./student-data.json");

/**
 * mock api client for retrieving student information
 */
module.exports = {
  getStudentInformation: (studentName) => {
    const message = 'loading student information for "' + studentName + '"';
    console.log(message.dim);
    return new Promise((resolve, reject) => {
      setImmediate(() => {
        resolve(studentData[studentName]);
      });
    });
  },
};


student-data.json

{
  "john": {
    "favoriteSubject": "Mathematics",
    "subjects": ["Physics", "Mathematics"]
  },
  "anthony": {
    "favoriteSubject": "Physics",
    "subjects": ["Physics", "Mathematics"]
  },
  "george": {
    "favoriteSubject": "History",
    "subjects": ["History", "Mathematics"]
  },
  "samuel": {
    "favoriteSubject": "Physics",
    "subjects": ["Physics", "History", "Geography", "Chemistry"]
  },
  "joseph": {
    "favoriteSubject": "Economics",
    "subjects": ["Economics", "Mathematics", "History"]
  }
}

Output

Running sequentially
loading student information...
loading student information for "samuel"
samuel CANNOT NOT have Physics as favorite subject as they do not study Mathematics
loading student information...
loading student information for "joseph"
joseph DOES NOT have Physics as favorite subject
loading student information...
loading student information for "anthony"
anthony HAS Physics as their favorite subject
Running parallelly (Promise.all)
loading student information...
loading student information...
loading student information...
loading student information for "samuel"
loading student information for "joseph"
loading student information for "anthony"
samuel CANNOT NOT have Physics as favorite subject as they do not study Mathematics
Dominant language
JavaScript
Stars
3.1k
Forks
507
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from CacheControl/json-rules-engine

All issues in CacheControl/json-rules-engine

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.