Issue encountered when attempting to convert currying into a promise chain

In our codebase, we have a utility function that wraps the axios http call. Currently, it is written in the form of currying with chained promises like this:

request<T>(request: AxiosRequestConfig, x: number, y: string, z: boolean): Promise<T> {
    return someFunction1(x)
             .then(someFunction2(y))
             .then(sendRequest(z))
             .catch((err) => { // handle error });
}
  function someFunction1(x: number): Promise<string> { }
  function someFunction2(y: string): (s: string) => Promise<AxiosRequestConfig> {}
  function sendRequest(z: boolean): (req: AxiosRequestConfig) => Promise<T> {
     // do other things...
     return axios.request<T>(req)
                 .then(processResponse);
  } 
  function processResponse(): (res: AxiosResponse<T>) => T { 
    // do other things...
    // do something with the res.
  }

To implement this, you can simply use

 await request(someReq, 1, 'hello', false)
. While this approach works fine, I now intend to convert it into async/await format as I want to inject a wrapper on the sendRequest function to include additional logic. Here is my attempt at conversion:

 // The sendRequest function now returns a normal promise instead of a function.
 function sendRequest<T>(z: boolean, req: AxiosRequestCofig): Promise<T> {
     // do other things...
     return axios.request<T>(req)
                 .then(processResponse);
 }

 // Define a function type
 type RealRequestCall<T> = (z: boolean, req: AxiosRequestConfig) => Promise<T>;

 // Implement the wrapper
 async function requestWrapper(z: boolean, req: AxiosRequestConfig, realRequest: RealRequestCall<T>): Promise<T> {

    if (!z) {
      // Simply forwards the request to the real request call.
      return realRequest(z, req).then(res => res);
    } else {
      const realResponse = await realRequestCall(z, req);
      // Manipulate the response here
     return Promise.resolve(realResponse);
    }
  
 }

 // The new request function now utilizes requestWrapper
function request<T>(request: AxiosRequestConfig, x: number, y: string, z: boolean): Promise<T> {
   return someFunction1(x)
                 .then(someFunction2(y))
                 .then(req => requestWrapper(z, req, sendRequest),
                       (err) => { // handle error });
}

However, when testing this implementation, I encountered two axios errors:

  1. Cannot set header after it's sent to client
  2. TypeError: Cannot read property 'processResponse' of undefined\n at sendRequest (/dist/util/http.util.js:102:24)\n at Object. (/dist/util/configProxy.js:20:20)

I am puzzled by these errors - what might be causing them during the conversion process?

Answer №1

It seems like the way you're approaching wrapping the function sendRequest may not be effective, as it includes the entire request response cycle within it (waiting for the response before returning).

You do have a few choices:

  1. Instead of simply wrapping, consider fully replacing sendRequest wherever it is used.
  2. Modify the interface of sendRequest so that it doesn't depend on waiting for the URL call to finish.
  3. Utilize axios's interceptors

Option 3 could be the most suitable as it is less intrusive, although it does come with a bit of "magic". If the client code is isolated or if the task is complex, options 1 or 2 might be preferred.

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

The React Native Flatlist encountered an error due to a mismatch in function overloads

I'm currently working on a React Native app using Typescript, and I've encountered an issue with the Flatlist renderItem function. As someone who is new to both Typescript and React Native, I received the following error message: No overload ma ...

Having trouble with image loading in NextJS after replacing an old image with a new one?

I have been attempting to swap out my current banner with different images to test if they work, but every image I try leads to an error when using next/image or even a simple <image> tag. The error message states that "The requested resource isn&apo ...

How to implement an instance method within a Typescript class for a Node.js application

I am encountering an issue with a callback function in my Typescript project. The problem arises when I try to implement the same functionality in a Node project using Typescript. It seems that when referencing 'this' in Node, it no longer points ...

Using Typescript to define the return value of an object's key value pair

Having just created the method getSpecificPlacementOption, I am faced with defining its return value in Typescript. As a newcomer to this language, I find myself unsure of how to go about it. Within my object called placementOptions, I aim to return a spec ...

Utilizing dual functions within the onChange event handler in React

I have a situation where I need to pass a function from a parent component to a child component through the onChange event, as well as another function in the child component to update its own state. How can I achieve this? Parent export function Fruits() ...

Does a typescript definition file exist for Apple MapKit JS?

Before embarking on creating one, I'm curious if anyone has come across a typescript definition file (.d.ts) for Apple MapKit JS? ...

What are the steps to set up a dictionary with predetermined values?

My task is to create a pre-defined dictionary where the key represents a city and the value is an array of zones in that city. Here is my attempt: export const cityToZone: { [city: string]: Array<string> } = [ {city:'New York', [&apos ...

Utilizing class-transformer to reveal an array of objects

I am facing an issue with exposing an array of objects in my code. Even though I have exposed the Followers array in the UserDto, it is not getting displayed as expected. This is the output I am currently seeing, { "id": "5ff4ec30-d3f4- ...

An issue has occurred: Unable to locate a supporting object 'No result' of type 'string'. NgFor is only compatible with binding to Iterables like Arrays

I am attempting to utilize this code to post data from a web service. service.ts public events(id: string): Observable<Events> { ...... return this.http.post(Api.getUrl(Api.URLS.events), body, { headers: headers }) .map((re ...

Creating a type declaration for an object by merging an Array of objects using Typescript

I am facing a challenge with merging objects in an array. Here is an example of what I am working with: const objectArray = { defaults: { size: { foo: 12, bar: { default: 12, active: 12 } }, color: {} } } ...

Assigning a value from an Angular Http subscription to a component variable is not allowed

Is there a way to retrieve data from an api and store it in a variable within an angular component? Specifically, I am attempting to assign the data received in the subscribe function to the loggedUser variable and then call a separate function within the ...

Disabling the ability to select Saturday and Sunday within the Ionic calendar application

I came across a tutorial online at "" that explains how to create an event calendar in Ionic. I followed the tutorial and successfully implemented it, but I now have a specific issue. I want to make Saturdays and Sundays unselectable, meaning users should ...

What is the best way to showcase both successful and failed API requests in a Next.js application?

I input the names of characters separated by commas, like Ricky, Marty, etc. Then, I send requests to a database for each character and display the results. How can I show a list of successful requests along with unsuccessful requests if a hero is not fo ...

Changing the child component input in Angular's deep cloning cannot be reflected on the user interface

I am currently working on a parent-child component setup. Within the parent component, I have a BehaviourSubject<SomeObject[]>(). export interface SomeObject(){ field: number; ... editable: boolean } Before passing the object to the child component, ...

"Learn how to trigger an event from a component loop up to the main parent in Angular 5

I have created the following code to loop through components and display their children: parent.component.ts tree = [ { id: 1, name: 'test 1' }, { id: 2, name: 'test 2', children: [ { ...

To determine if two constant objects share identical structures in TypeScript, you can compare their properties

There are two theme objects available: const lightMode = { background: "white", text: { primary: "dark", secondary: "darkgrey" }, } as const const darkMode = { background: "black", text: { prim ...

Exploring the best way to access ViewContainerRef: ViewChild vs Directive

While researching, I came across a recommendation in the Angular Docs that suggests using a directive to access the ViewContainerRef for creating dynamic components. Here is an example of such a directive: import { Directive, ViewContainerRef } from &apos ...

What is the rationale behind TypeScript's decision to permit omission of "this" in a method?

The TypeScript code below compiles without errors: class Something { name: string; constructor() { name = "test"; } } Although this code compiles successfully, it mistakenly assumes that the `name` variable exists. However, when co ...

Problem with rendering React Router v4 ConnectedRouter on nested routes

The routes for the first level are correctly displayed from Layout.tsx, but when clicked on ResourcesUI.tsx, the content is not rendered as expected (see code below). The ResourceUI component consists of 2 sections. The left section contains links, and th ...

Display the value function within an Angular template

I am attempting to calculate the sum of a value in an array obtained from an HTTP GET method and a subscribe function. I want to display the result in the HTML but it is not working. I really hope someone can assist me with this because I am stuck. Here ...