Parsing and Evaluating Expressions from Backend in JavaScript

Introduction

In modern web applications, dynamically evaluating expressions based on data retrieved from a backend database is a common requirement. This functionality is crucial for scenarios such as dynamic form validations, conditional rendering, and complex business logic implementations. In this blog post, we will explore how to parse a string expression, fetched from a backend database, and evaluate it using JavaScript. We will provide a detailed explanation of a sample code that achieves this, showcasing its practical use cases and step-by-step implementation.

Use Cases

  1. Dynamic Form Validations: Validate form inputs based on complex rules stored in the backend.
  2. Conditional Rendering: Render UI components conditionally based on expressions retrieved from the server.
  3. Business Logic Implementation: Apply business rules that are dynamically defined in the backend.
  4. Data Filtering: Filter datasets on the client side based on conditions provided by the backend.

Current Approaches

Currently, evaluating expressions dynamically often involves:

  • Manual Parsing and Evaluation: Manually parsing the expression string and using JavaScript’s eval() function, which poses security risks.
  • Libraries and Frameworks: Utilizing third-party libraries designed for expression evaluation, can add extra dependencies and complexity.
  • Custom Solutions: Creating bespoke solutions tailored to specific use cases, which can be efficient but require careful implementation to avoid security and performance issues.

Steps to parse and evaluate expressions
 

Step 1. Define the data structure

Consider the following data structure, which represents user contact information and other details.

const myData = {
  Contact: {
    FirstName: "Dharmi",
    UserId: "32342",
    Age: 24
  },
  User: {
    Name: "Max",
    City: "Trichy"
  }
};

Step 2. Create the function for evaluating expressions

The core function ReturnExpressionResult is designed to parse a string expression and evaluate it based on the provided data. This function takes two parameters: the expression string and the data object.

function ReturnExpressionResult(input, data) {
  const sanitizedInput = input.replace(/\[|\]/g, "");

  const func = new Function('data', `with (data) { return ${sanitizedInput}; }`);
  try {
    return !!func(data);
  } catch (error) {
    console.error("Error evaluating expression:", error);
    return false;
  }
}

Step 3. Sample expressions and evaluation

Let's evaluate a few sample expressions using the ReturnExpressionResult function.

const input1 = "[Contact.FirstName != '']";
const input2 = "[Contact.Age]";
const input3 = "[Contact.FirstName !='' && Contact.UserId !=''] && !User.City";
const input4 = "([Contact.FirstName !='' && Contact.UserId !='']) || [User.Name.length > 0]";
console.log("Result1: ",ReturnExpressionResult(input1, myData)); // true
console.log("Result2: ",ReturnExpressionResult(input2, myData)); // true
console.log("Result4: ",ReturnExpressionResult(input3, myData)); // false
console.log("Result5: ",ReturnExpressionResult(input4, myData)); // true

This will output

Output

Conclusion

By implementing a custom function to parse and evaluate expressions from a backend database, we can dynamically apply complex logic based on structured data. This approach provides flexibility, efficiency, and control, making it a valuable tool for various web development scenarios. However, it's crucial to handle expression evaluation carefully to avoid security risks, especially when dealing with user-generated content.