Traversing a sequence of method calls within a Promise object (as the return type)

In software development, there is a classic technique where a method returns the result of another method call:

method1(): ObjectX {
   if( condition1 )
      return method2();

   return undefined // or some default value;
}

method2(): ObjectX {
  let res: ObjectX;
  // some IO operations
  return res;
}

However, I am now interested in utilizing Promise<ObjectX> as the return type of method2 (due to potential IO operations).

This modification transforms method2 into:

method2() : Promise<ObjectX> {
  return new Promise((resolve)=> {
     let res: ObjectX;
     // some IO operations
     resolve(res);
  })
}

The challenge lies in method1.

Why CAN'T IT BE structured like this:

method1() : Promise<ObjectX> {
   if( condition1) 
      return this.method2(); 

   return new Promise((reject)=> { reject('error'); })
}

Why must a method that needs to return a promise NOT be able to return the result of another method (which also returns a Promise)?

Why is it necessary for the method to "unpack" the received promise, extract the result, and then resolve its own Promise with this result?

For example, why do we have to structure it like this:

method1() : Promise<ObjectX> {
    return new Promise((resolve, reject) => {
       if( condition1) 
          method2().then( (r) => resolve(r) ); // extracting result from received promise and resolving my own

       reject('error'); 
    });

I mean, this approach works, but I am curious about why the previous method1 implementation doesn't suffice.

More broadly, imagine a chain of methods calling each other and passing an object along. If I introduce a Promise in the final method's return type, I find myself needing to extensively modify all methods in the sequence - not just their signatures and return statements.

Is there an alternative technique to achieve this without such significant code modifications?

Answer №1

The implementation of your method1 is overly complicated:

method1() {
   if(condition1) 
      return Promise.resolve(method2());
   return Promise.reject(‘error’); 
}

You don't need to specify a return type, as TypeScript will correctly infer that it is a Promise<ObjectX>.

Simplifying further:

async method1() {
   if(condition1) 
      return method2();
   throw 'error';
}

Both versions have the correct return type of Promise<ObjectX>, regardless of whether method2() returns ObjectX or Promise<ObjectX>. Wrapping promises unnecessarily just adds complexity.

The reason why your initial code did not work as expected:

return new Promise((reject)=> { reject(‘error’); })

is because creating a promise with Promise.reject(something) has a return type of Promise<never>, which then simplifies down to Promise<ObjectX> when combined with your Promise<ObjectX>.

If you modify the code slightly, like so:

return new Promise<never>((reject)=> { reject(‘error’); })

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 best way to display multiple HTML files using React?

Looking to develop a web application using React that consists of multiple HTML pages. For instance, login.html and index.html have been created and linked to URIs through the backend - resulting in localhost:8080/login and localhost:8080/index. However, R ...

How can I change the CSS class of my navbar component in Angular 2 from a different component?

Here is a custom progress bar component I created: @Component ({ selector: 'progress-bar', templateUrl: './progress-bar.component.html', styleUrls: ['./progress-bar.component.css'] }) export class ProgressBarComponent ...

Concealing the sidebar in React with the help of Ant Design

I want to create a sidebar that can be hidden by clicking an icon in the navigation bar without using classes. Although I may be approaching this incorrectly, I prefer to keep it simple. The error message I encountered is: (property) collapsed: boolean ...

The Tanstack react-table feature is limited in its ability to output tsx from the cell

Currently conducting a test on Tanstack react-table library using React and TypeScript. It appears that I am encountering an issue with returning tsx/jsx from the cell function of ColumnDef: Is there something crucial that I seem to be overlooking in this ...

Using RxJS and the combineLatest function can be hit or miss in terms of reliability

When you call this function multiple times with the values of observables obs1 and obs2 being the same each time, the returned array may not always be the same. getUniqueProducts(obs1: Observable<any>, obs2: Observable<any>): Observable<any& ...

Improving DynamoDb Query Results with Type Hinting

In the following Typescript code, how can I specify which fields should be present in my Query Items Result? const request: DynamoDB.DocumentClient.QueryInput = { TableName: UnsubscriptionTokensRepository.TABLE_NAME, IndexName: 'TokenIndex&ap ...

What is the best way to generate a dynamically interpolated string in JavaScript?

I'm currently developing a reusable UI component and am exploring options to allow the user of this component to provide their own template for a specific section within it. Utilizing TypeScript, I have been experimenting with string interpolation as ...

Can you please provide instructions on how to obtain the TypeScript definitions file for a specific version of Jquery, such as 3.2.1

As I navigate my way through TypeScript, I find myself in need of accessing type definitions for a jQuery project in Visual Studio. The project currently utilizes jquery version 3.2.1, and I'm on the lookout for TypeScript type definitions for it. Af ...

Endless Cycle of Promise and useState Hook

I'm struggling with a situation where I unintentionally created an infinite loop using a combination of a fetch promise and a useState hook in React. Could someone shed some light on why this loop keeps repeating? My understanding of both concepts is ...

Create a Typescript type extension specifically designed for objects with nested arrays of objects

After stumbling upon this inquiry, I am eager to adjust my code in a similar fashion, utilizing typescript and a more intricate object. Consider the type below: export type ImportationType = { commercialImportation: boolean dateToManufacturer: string ...

Issues encountered when integrating ag-grid-react with typescript

Despite extensive searching, I am unable to find any examples of utilizing ag-grid-react with TypeScript. The ag-grid-react project does have TypeScript typing available. In my React app, I have installed ag-grid-react: npm i --save ag-grid ag-grid-react ...

Capable of retrieving information from an API, yet unable to display it accurately within the table structure

I'm currently working with Angular version 13.2.6 and a .NET Core API. I have two components, PaymentdetailsView (parent) and PaymentDetailsForm (child). Within the PaymentDetailsForm component, there is a form that, when submitted, makes a call to ...

Resolving NestJS Custom Startup Dependencies

In my setup, I have a factory responsible for resolving redis connections: import {RedisClient} from "redis"; export const RedisProvider = { provide: 'RedisToken', useFactory: async () => { return new Promise((resolve, reject ...

What is the best choice for storing data in my Angular2+ component: an object or an observable?

If I were to create an angular2+ component that fetches data from an API and displays its name, which approach would be considered more idiomatic? Initial Strategy: Using thing as an object In this scenario, the component subscribes to a websocket observ ...

What is causing my function to execute twice in all of my components?

One issue I am facing is that I have created three different components with routing. However, when I open these components, they seem to loop twice every time. What could be causing this behavior and how can I resolve it? For instance, in one of the comp ...

Resolving Node.js Absolute Module Paths with TypeScript

Currently, I am facing an issue where the modules need to be resolved based on the baseUrl so that the output code is compatible with node.js. Here is my file path: src/server/index.ts import express = require('express'); import {port, database ...

How to format a Date object as yyyy-MM-dd when serializing to JSON in Angular?

I have a situation where I need to display an object's 'birthDate' property in the format DD/MM/YYYY on screen. The data is stored in the database as YYYY-MM-DD, which is a string type. I am currently using bootstrap bsDatePicker for this ta ...

Ways to extract repeated value from a function?

Currently, I am working with two files. One file contains a script that generates a token, while the other file handles that token. The issue arises with the second script, as it only logs the initial token received and does not update with any new values ...

Tips for optimizing the performance of nested for loops

I wrote a for loop that iterates over 2 enums, sending them both to the server, receiving a value in return, and then calculating another value using a nested for loop. I believe there is room for improvement in this code snippet: const paths = []; for awa ...

Breaking down nested arrays in typescript

After receiving a response from the service, the data included the following: "rows": [ [ "stravi/aa", "202001", "59", "51", "2558.98", "0.5358894453719162", "1.9204668112983725", "140", "2.346630 ...