Guide on setting up multiple Axios instances in NestJS

I'm in the process of migrating an existing Express application to NestJS. Currently, I have a configuration file where I define multiple axios instances for each microservice:

export const writeModelApi = axios.create({
  baseURL: getWriteModelApiUrl(),
});

export const readModelApi = axios.create({
  baseURL: getReadModelApiUrl(),
});

export const configApi = axios.create({
  baseURL: getConfigApiUrl(),
});

function addCamelizeInterceptors(api: any) {
  // Interceptor logic
}

addCamelizeInterceptors(taskingApi);
addCamelizeInterceptors(readModelApi);
addCamelizeInterceptors(configApi);

I've been thinking about how to replicate this functionality using shared modules in NestJS. Currently, I have set up the following:

  • ReadModelModule
@Module({
  imports: [
    HttpModule.register({
      baseURL: getReadModelApiUrl(),
    }),
  ],
  providers: [ReadModelService],
  exports: [ReadModelService],
})
export class ReadModelModule implements OnModuleInit {
  constructor(@Inject() private httpService: ReadModelService) {}

  public onModuleInit() {
    addCamelizeInterceptors(this.httpService.axiosRef);
  }
}

  • ReadModelService
@Injectable()
export class ReadModelService extends HttpService {}

However, Nest is throwing an error message that reads:

[ExceptionHandler] Nest can't resolve dependencies of the ReadModelModule (?). Please make sure that the argument dependency at index [0] is available in the ReadModelModule context.

Potential solutions:
- If dependency is a provider, is it part of the current ReadModelModule?
- If dependency is exported from a separate @Module, is that module imported within ReadModelModule?
  @Module({
    imports: [ /* the Module containing dependency */ ]
  })

I'm struggling with resolving this issue and would appreciate any guidance or help. Thank you!

Answer №1

After some exploration, I came up with a creative workaround. While going through the NestJs code, I discovered that extending the HttpService was not straightforward due to the unavailability of the provider constant (AXIOS_INSTANCE_TOKEN) required for its constructor.

To resolve this limitation, I developed my own version of the HttpModule and included the essential constant to enable my service to extend HttpService seamlessly.

Below is the snippet of my solution:

MyHttpModule:

export const AXIOS_INSTANCE_TOKEN = "AXIOS_INSTANCE_TOKEN";

@Module({
  providers: [
    ReadModelService,
    {
      provide: AXIOS_INSTANCE_TOKEN,
      useValue: Axios,
    },
  ],
  exports: [ReadModelService],
})
export class MyHttpModule {}

ReadModelService:

@Injectable()
export class ReadModelService extends HttpService {
  constructor() {
    const instance = Axios.create({
      baseURL: getReadModelApiUrl(),
    });
    addCamelizeInterceptors(instance);

    super(instance);
  }
}

With this implementation, I can utilize the ReadModelService similarly to HttpService but with added functionalities such as baseURL and axios interceptors. Furthermore, I have replicated a similar approach for WriteModelService and other services. While this might not be the most optimal solution available, it serves its purpose effectively with minimal code necessary.

Answer №2

Consider including HttpService in the providers: [] array within the ReadModelModule

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

Is there a way to refresh a Material-UI data table in React whenever a user takes any action?

I am facing an issue with my Lock-Unlock button and delete button. The problem arises when I render data from axios using the useEffect hook, it works fine. However, if I try to lock or unlock a user, the table does not update automatically. This indicates ...

How to remove a specific type from a generic type in Typescript without using Exclude<>?

I am looking for a solution to prevent my function from working with Moment objects when storing values in local storage. Currently, the function dynamically stringifies and stores values, but I want to exclude Moment objects from being processed. Here is ...

What are the steps to achieve complete test coverage for my Angular login form? Encountering an issue with reading property 'subscribe' of undefined

Recently, I made adjustments to my login component to align more closely with Angular standards. However, upon testing, I encountered errors of this kind: Cannot read property 'subscribe' of undefined After using console.log for debugging pur ...

Do Angular lifecycle hooks get triggered for each individual component within a nested component hierarchy?

I'm exploring the ins and outs of Angular lifecycle hooks with a conceptual question. Consider the following nested component structure: <parent-component> <first-child> <first-grandchild> </first-grandchild& ...

Organize routes into distinct modules in Angular 6

Currently grappling with routing in my Angular 6 application. Wondering if the structure I have in mind is feasible. Here's what it looks like: The App module contains the main routing with a parent route defining the layout: const routes: Routes = ...

Integrating concealed elements into jspdf

I am currently working on incorporating a hidden div into my jspdf file. Utilizing html2canvas for this purpose, I find it necessary to briefly make the div visible, add it to the pdf, and then hide it again. This method is not ideal as the content moment ...

The variable isJoi has been set to true but there is an error due to an unexpected

I am currently developing a NestJs backend on multiple machines. One of the machines is experiencing issues with the @hapi/joi package. When running the NestJs application in development mode on this specific machine, I encounter the following error: PS C ...

Tips on displaying a spinner only when data is retrieved from an Http service

How can I ensure that a spinner is only shown during an HTTP service call and dismissed when my component receives data? To address this issue, I implemented a cache service to store data fetched from the HTTP service for future use. However, I want to sh ...

Transmit information using JSON format in Angular 8 using FormData

i am struggling with sending data to the server in a specific format: { "name":"kianoush", "userName":"kia9372", "email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bcd7d5ddd8ce85...@example.com</a>" } H ...

Is there a way to utilize the 'interval' Rxjs function without triggering the Change Detection routine?

My goal is to display the live server time in my application. To achieve this, I created a component that utilizes the RXJS 'interval' function to update the time every second. However, this approach triggers the Change Detection routine every se ...

Convert individual packages within the node_modules directory to ES5 syntax

I am currently working on an Angular 12 project that needs to be compatible with Internet Explorer. Some of the dependencies in my node_modules folder are non es5. As far as I know, tsc does not affect node_modules and starts evaluating from the main opti ...

Are there any alternative methods to define a constructor function in TypeScript that do not involve utilizing classes? Upon researching on this subject, it appears that all sources suggest using classes

Is it possible to transform this class declaration into a constructor function without losing TypeScript compatibility? class Animal { constructor(public name: string, public energy: string) {} } ...

Getting the readonly-item type from an array in TypeScript: A step-by-step guide

Is it possible to create a readonly item array from a constant array? const const basicValueTypes = [{ value: 'number', label: 'Number' },{ value: 'boolean', label: 'Boolean' }]; type ReadonlyItemArray = ??? ...

Personalized path-finding tree iterator

I am trying to implement a custom iterator in JavaScript that can traverse a DOM tree based on specific criteria provided by a callback function. The goal is to return an array of the nodes that match the criteria as the generator iterates through the tree ...

The script resource is experiencing a redirect that is not permitted - Service Worker

I have integrated a Service Worker into my Angular application, and it works perfectly when running on localhost. However, when I attempt to deploy the code in a development or different environment, I encounter the following error: Service worker registra ...

How is it that in TypeScript, a potential numeric value in an interface can be transformed into an impossible numeric value in a class implementation?

Encountered a surprising behavior from the TypeScript compiler today. Unsure if it's a bug or intentional feature. If it is indeed intentional, I would like to understand the reasoning behind it. The issue arises when declaring an interface method wi ...

Differences between TypeScript `[string]` and `string[]`

When using TypeScript, which option is the correct syntax? [string] vs string[] public searchOption: [string] = ['date']; public searchOption: string[] = ['date']; ...

Using Angular to make an HTTP POST request to fetch data

My trusty .net backpack has been working flawlessly. However, I encountered an issue when trying to connect it with the Angular front end. All backend requests are post requests and require passing an ApiKey in the body of each request. Interestingly, ever ...

What is the method to remove curly brackets from a different data category?

If I have a type like this type Z = {a: number} | {} | {b: boolean} | {c: string} | ...; Is there a way to get the same type but without {}? type Y = Exclude<Z, {}>; ⇧This will result in Y = never, because all variants can be assigned to {} and a ...

AngularFire2 Firestore Custom Query: retrieve documents based on current date and time.startTime

Welcome to the world of AngularFire2 and Firestore! My objective is clear: Query data from Firestore where startTime matches currentDateRange. I am facing some challenges with creating a dynamic query in Firestore. After going through the official docume ...