Determining the specific condition that failed in a series of condition checks within a TypeScript script

I am currently trying to determine which specific condition has failed in a set of multiple conditions. If one does fail, I want to identify it. What would be the best solution for achieving this?

Here is the code snippet that I am using:

const multiCondition =
  (await firstCondition()) &&
  (await secondCondition()) &&
  (await thirdCondition());

if (multiCondition) {
...
} else {
  // Failed! Which condition caused the failure?
}

Edit:

Note: Each condition is dependent on the success of the previous one.

Answer №1

At this moment, your promises are executing serially. Is this by design? If you prefer them to run in parallel, you can easily check the status of each using Promise.allSettled.

If you want them to execute sequentially, you could loop through all the conditions and stop if any fails, returning a failure status for the remaining promises. If all conditions pass, it will return an empty object.

const conditions = [firstCondition, secondCondition, thirdCondition];

const result = await conditions.reduce(async (status, condition, index) => {
   // Skip running current condition if we've already failed
   // Return failure status instead
   if(status.failed) {
     return status;
   }

   // Run the condition
   const test = await condition();

   // Return accumulator if successful, set status as failed if not
   return test ? status : { failed: true, failedAt: index }
}, {});

if(result.failed) {
   console.log('Condition failed: ', conditions[result.failedAt]);
}

You can simplify the code above like this:

const conditions = [firstCondition, secondCondition, thirdCondition];

const result = await conditions.reduce(async (status, condition, index) =>
  status.failed ?
  status :
  await condition() ?
  status :
  { failed: index },
  {}
);

if('failed' in result) {
   console.log('Condition failed: ', conditions[result.failed]);
}

Next, organize it into a utility function:

const promiseAnd = async (...conditions) => await conditions.reduce(async (status, condition, index) =>
  status.failed ?
  status :
  await condition() ?
  status :
  { failed: index },
  {}
);

const { failed } = await promiseAnd(firstCondition, secondCondition, thirdCondition);
if(failed) {
  console.log(`Promise ${failed} failed`);
}

Answer №2

const check1 = await validateFirst();
const check2 = await validateSecond();
const check3 = await validateThird();

const allChecks =
  check1 &&
  check2 &&
  check3;

if (allChecks) {
...
} else {
  // Error on which condition?
  // - Check 1
  // - Check 2
  // - Check 3
}

Answer №3

An effective approach is to utilize separate 'if' statements for each condition.

Answer №4

Here is my approach to achieving the desired outcome:

const criteria = [await conditionOne(), await conditionTwo(), await conditionThree()];

// checking all conditions
const areAllMet = criteria.reduce((current, next) => current && next);

if (areAllMet) {
  // success
} else {
  if (!criteria[0]) {
    // condition one failed
  } else if (!criteria[1]) {
    // condition two failed
  } else if (!criteria[2]) {
    // condition three failed
  } else {
    throw new Error('Unexpected error occurred');
  }
}

Answer №5

To efficiently exit the surrounding function, I recommend using guard clauses. Since your async checks are already executed sequentially, you can simplify the code like this:

if (!await firstCondition()) {
  // first condition failed
  return; // or throw
}

if (!await secondCondition()) {
  // second condition failed
  return; // or throw
}

if (!await thirdCondition()) {
  // third condition failed
  return; // or throw
}

// all conditions passed successfully
// ...

If you prefer not to exit, you have the option of using else-if statements instead.

if (!await thirdCondition()) {
  // first condition failed
} else if (!await secondCondition()) {
  // second condition failed
} else if (!await thirdCondition()) {
  // third condition failed
} else {
  // all conditions passed successfully
  // ...
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the reason for a boolean extracted from a union type showing that it is not equivalent to true?

I'm facing a general understanding issue with this problem. While it seems to stem from material-ui, I suspect it's actually more of a typescript issue in general. Despite my attempts, I couldn't replicate the problem with my own types, so I ...

Issue with firestore IN query when encountering NULL value

Is there a way to create a query that retrieves all documents without a value, whether it be null or ''? Within my table are three documents, each containing a field called a. During an IN query, the document with the null value is not being re ...

Exploring alternatives to ref() when not responsive to reassignments in the Composition API

Check out this easy carousel: <template> <div ref="wrapperRef" class="js-carousel container"> <div class="row"> <slot></slot> </div> <div class=&q ...

How to eliminate ampersands from a string using jQuery or JavaScript

I'm having trouble with a seemingly simple task that I can't seem to find any help for online. My CSS class names include ampersands in them (due to the system I'm using), and I need to remove these using jQuery. For example, I want to chan ...

What is the reason behind the browser crashing when a scrollbar pseudo-class is dynamically added to an iframe?

1. Insert a new iframe into your HTML: <iframe id="iframe-box" onload=onloadcss(this) src="..." style="width: 100%; border: medium none; "></iframe> 2. Incorporate the following JavaScript code into your HTML file ...

Finding elements based on their position using Javascript

I'm searching for an optimal method to identify all elements located within a specific range of pixels from the top of the page. Currently, I have implemented a straightforward test called inRange function inRange(el, from, to) { var top = el.offs ...

Issue with extending mongoose.Document properly in NodeJS and TypeScript using a custom interface with mongoose

I recently started learning Typescript and tried to follow this guide to help me along: After following the guide, I implemented the relevant code snippets as shown below: import { Document } from "mongoose"; import { IUser } from "../interfaces/user"; ...

Improve the Popup to seamlessly elevate

In my project, I have implemented a pop-up dialog box that rises up from the left bottom corner as the user scrolls down the page. You can view it live at this link- However, I am facing an issue where the initial lift up of the dialog box is not smooth, ...

Obtain information from the get request route in Node.js

I've been diving into nodejs and databases with the help of an online resource. As part of my learning process, I have been tasked with replicating the code below to fetch data from app.use('/server/profil'); However, I'm encountering ...

What is the correct way to wrap an http.get in TypeScript?

My understanding of Typescript is limited, so I have a basic question related to my web application's frontend. In most http get-requests, I need to include two parameters. To simplify this process, I created a simple wrapper for HttpClient (from "ang ...

Is it possible to modify this code to accept multiple IDs at once?

I'm attempting to create a form in JavaScript where, upon entering the necessary details and clicking submit, the user's email client opens with the information pre-filled for easy sending. However, I am facing challenges as my code involves mult ...

Tips for incorporating HTML code within a select option value?

I am working with AngularJS to create a Visual Composer for a website. One feature I want to incorporate is the ability to add HTML code based on the selection made in a dropdown menu. However, I am struggling to figure out how to include the HTML within t ...

Derive a subset Union from a Union in Typescript

Here is a scenario with a Union type I'm working with; type MyUnionType = 'foo' | 'bar' | 'baz' What I need to do is create a new Union called MySubUnion, which will be a subset of the original; type MySubUnion = &apos ...

Inverted Scrolling Problem in Firefox

I am facing an issue with a script that inverts mouse movement for horizontal scrolling. It works fine in most browsers except Firefox. I could use some advice on how to troubleshoot this problem! $("body").mousewheel(function(event, delta) { ...

Troubleshooting the Nextjs-blog tutorial loading issue on localhost:3000

Looking to delve into Nextjs, I decided to start by following a tutorial. However, every time I attempt to run 'npm run dev', the local host just keeps loading endlessly. Upon inspecting and checking the console, there is no feedback whatsoever. ...

Decoding SQS POST messages using node.js

I am faced with the challenge of setting up communication between a web server and a worker using an SQS. The process involves uploading an image to an S3 bucket through the server, which then sends a message to the SQS for the worker to retrieve, resize, ...

Enigmatic Cartography Classification

In my attempt to construct a specialized Map-like class that maps keys of one type to keys of another, I encountered a challenge. A straightforward approach would be to create a Map<keyof A, keyof B>, but this method does not verify if the member typ ...

Please restrict all scores to only one decimal point and ensure that all integer scores include a ".0" at the end, except for scores of 10 or 0

Ensure scores are rounded to a single decimal point and update all integer values with .0, except for 10 and 0. For example: 0.972 should be 0.9 2.83 should be 2.8 All integer scores will be updated as: 0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10 I have ...

Error encountered: The token transfer cannot be completed due to an invalid address

Whenever I attempt to send a token from one address to another, I keep encountering the error mentioned in the title. Below is the relevant snippet of my JavaScript code: tokenContract.transfer($("#targetAddr").val().toString(), $("#amt" ...

When a promise is executed, it runs the code synchronously regardless of the promise

Essentially, I have a web application that fetches data from Firebase. Due to the time it takes to retrieve this data, I've implemented promises in JavaScript to ensure my code executes at the appropriate times. Within the function getDataFirebase, in ...