The combination of Nest, Fastify, Fastify-next, and TypeOrm is unable to locate the next() function

In my attempt to set up Nest with Fastify and Next using the fastify-next plugin, everything went smoothly until I added TypeOrm for MongoDB integration. Upon loading the AppModule, Nest throws an error indicating that the .next() function cannot be found in the fastify instance after the fastify-next plugin is initialized.

Code

// main.ts
async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  await app.init();

  const configService = app.get<ConfigService<IConfigTypes>>(ConfigService);
  const appConfig = configService.get<IAppConfig>('app');

  const fastify = await app.register(fastifyNext, {
    dev: appConfig.isDev,
    dir: appConfig.clientPath,
  });

  fastify.after(() => {
    appConfig.staticRoutes.forEach((page) => fastify.next(page));
  });

  await app.listen(appConfig.port);
  Logger.log(`🚀 Server is running on port ${appConfig.port}`, 'Bootstrap');
}
bootstrap();
// app.module.ts
@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
      isGlobal: true,
      cache: true,
      load: [appConfig, shopifyConfig, databaseConfig],
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService<IConfigTypes>) => {
        const dbConfig = configService.get<IDatabaseConfig>('database');
        const { type, host, base, user, pass } = dbConfig;

        let url = 'mongodb+srv://';
        url += `${user}:${pass}@${host}/${base}`;
        url += '?retryWrites=true&w=majority';

        return {
          type,
          url,
          entities: [join(__dirname, '**/**.entity{.ts,.js}')],
          synchronize: true,
          useNewUrlParser: true,
          logging: true,
        };
      },
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

Console Output with Error:

[8:45:52 AM] File change detected. Starting incremental compilation...

[8:45:52 AM] Found 0 errors. Watching for file changes.

[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [NestFactory] Starting Nest application...
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] AppModule dependencies initialized +26ms
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +0ms
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] ConfigHostModule dependencies initialized +1ms
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 26331  - 08/23/2021, 8:45:53 AM     LOG [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 26331  - 08/23/2021, 8:45:55 AM     LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +2361ms
[Nest] 26331  - 08/23/2021, 8:45:55 AM     LOG [NestApplication] Nest application successfully started +5ms

/dir/to/project/node_modules/avvio/boot.js:533
      res = func()
            ^
TypeError: fastify.next is not a function
    at /dir/to/project/src/server/main.ts:30:54 ===> appConfig.staticRoutes.forEach((page) => fastify.next(page));

To address this issue temporarily, I am currently waiting for the .next() function to become available in the fastify instance before executing the code. However, I believe there should be a better way to resolve this problem.

Modified Code:

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  await app.init();

  const configService = app.get<ConfigService<IConfigTypes>>(ConfigService);
  const appConfig = configService.get<IAppConfig>('app');

  const fastify = await app.register(fastifyNext, {
    dev: appConfig.isDev,
    dir: appConfig.clientPath,
  });

  await new Promise((res) => {
    const launch = async () => {
      if (!fastify.next) {
        setTimeout(launch, 200);
        return;
      }

      appConfig.staticRoutes.forEach((page) => fastify.next(page));
      await app.listen(appConfig.port);
      Logger.log(`🚀 Server is running on port ${appConfig.port}`, 'Bootstrap');
      res(null);
    };

    launch();
  });
}
bootstrap();

The error disappears when I remove the TypeOrmModule from AppModule, indicating that the issue may stem from the asynchronous loading of the Module forRootAsync.

If you have any insights or better solutions to rectify this problem, please feel free to share. Thank you!

Answer №1

In order to solve the issue, I utilized FastifyInstance from Nest.js HTTPAdapter to register the plugin. Additionally, a promise was implemented to ensure that Fastify registers the plugin before starting the application by listening to the port.

  await app.init();

  const configService = app.get<ConfigService<IConfigTypes>>(ConfigService);
  const appConfig = configService.get<IAppConfig>('app');
  const fastify = app.getHttpAdapter().getInstance() as FastifyInstance;

  await new Promise((resolve) => {
    fastify
      .register(fastifyNext, {
        dev: appConfig.isDev,
        dir: appConfig.clientPath,
      })
      .after(async () => {
        appConfig.staticRoutes.forEach((route) => fastify.next(route));
        resolve(null);
      });
  });

  await app.listen(appConfig.port);
  Logger.log(`🚀 Server is running on port ${appConfig.port}`, 'Bootstrap');

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

Saving Pictures in Database Without Using jQuery

Hey there fellow developers, I'm currently immersed in a web project that involves reconstructing a social media platform similar to snapchat. To capture images, I am utilizing my webcam with JavaScript and saving the image data to a variable named i ...

Adding a class to the following DIV and smoothly transitioning the current one out can be achieved using a dynamic number of items in multiple instances

Is there a way to create a scalable CSS slideshow for text divs without using images? Here is the current HTML structure: <div class="mb-panel-container cf"> <div class="mb-panel-section mb-slider"> <div class="mb-panel active" ...

Receiving an unanticipated value from an array

Actions speak louder than words; I prefer to demonstrate with code: //global variable var siblings = []; var rand = new Date().getTime(); siblings.push('uin_' + rand); alert(siblings['uin_' + rand]); // undefined Why is it coming up ...

I recently discovered how to modify the video source (src) within an html5 source tag, but I am encountering varied outcomes when using it within a function or with inline javascript

When attempting to change the src of a video tag using Javascript, I encountered an issue. The code works fine when placed inline, but as soon as I try to include it within a function or in the "onclick" event of a button tag, nothing happens. There are no ...

Encountered a 400 error when attempting to send a request to a RestController in Spring MVC

I keep getting a "bad request 400" error when sending a request with parameters to the controller. I have double-checked the syntax but can't find any mistakes. Can someone please review my code and see what's wrong? var url = contextPath+"/bill ...

The addClass and removeClass functions seem to be malfunctioning

Hey everyone, this is my first time reaching out for help here. I looked through previous questions but couldn't find anything similar to my issue. I'm currently working on a corporate website using bootstrap3 in Brackets. I've been testing ...

React JS - Building a dynamic multi-tiered dropdown navigation system

Link to view the illustrative example: here. Could anyone advise on a solution for ensuring only one submenu is open at a time? For instance, when "menu 3" is opened, I would like "menu 2" to be automatically closed. ...

The issue of passing a local object from ng-repeat into a directive controller remains unresolved

I'm struggling to pass my local object from ng-repeat to a directive. My goal is to access the data from that object within the controller of the directive. The confusion arises with how the isolated scope and controller scope interact. I can't f ...

Is it possible to pass the image source to a Vue.js component through a

I am encountering an issue while trying to display an image in the designated location within display.vue. Even though {{ someText }} returns the correct file path (../assets/city.png), the image is not being output correctly. Here is how my code looks: ...

Getting specific information from a cell in a table within an AngularJS application

I need to extract the data "Crab" from this table: Sushi Roll FishType Taste Level Cali Roll Crab 2 Philly Tuna 4 Rainbow Variety 6 Tiger Eel 7 Here is the code snippet that currently re ...

The useEffect function is failing to execute, leading to an issue with an undefined variable

Attempting to retrieve a specific string with the help of useRouter, then utilizing that same string to access a particular document from Firebase is my current goal. This sequence of actions is supposed to take place within the confines of the useEffect f ...

Error message: When attempting to create dynamic inputs in React, an error occurs stating that instance.render is not

I encountered an issue while attempting to create dynamic inputs in React. The error message 'TypeError: instance.render is not a function' keeps popping up. import React, { Component } from 'react'; import Input from '../../Ui/Inp ...

Experiencing difficulties when utilizing Jest to test components

I recently started working with Jest and JavaScript. I wrote a test for one of my components, but it's failing, and I'm struggling to figure out what's wrong (seems like something related to enzyme). Here is the output: ● Console co ...

What is the process of sending a modified array as text to TextEdit?

As a beginner in JXA, I am currently learning how to perform simple tasks in TextEdit. I have managed to extract the paragraphs of a document and store them as an array using the following code: app = Application('TextEdit') docPars = app.docu ...

The scatterplot dots in d3 do not appear to be displaying

My experience with d3 is limited, and I mostly work with Javascript and jQuery sporadically. I am attempting to build a basic scatterplot with a slider in d3 using jQuery. The goal of the slider is to choose the dataset for plotting. I have a JSON object ...

What potential issues arise from utilizing useRef alongside useSelector?

Although I have the capability to access the store by using thunks and/or global stores, I avoid binding my component to the Redux store. This is because the component will be utilized with various stores both inside and outside of the project. The compone ...

Encountering issues with setting up the <title> and <meta> tags in a Next.js

I recently developed a dynamic web page. It works perfectly fine when I test it on localhost; the title and meta tags are visible without any issues. However, after building the project, I noticed that the view page source does not display the title and me ...

The JQUERY Uncaught Error: Syntax error message popped up when trying to access an unrecognized expression on the javascript: void(0)

I've encountered an issue after upgrading to jQuery 3.4.1 while using bootstrap 3. The console keeps showing this error: Uncaught Error: Syntax error, unrecognized expression: # Here is the section of code causing the error: <div class="btn-grou ...

show a pie chart at the top of the div using highcharts

i am struggling with positioning the high-chart with a label, as seen in the image below https://i.sstatic.net/m9bXW.png does anyone know how to properly display the chart from the top left corner? i have attempted to adjust the settings like this { ...

How should one go about creating an npm package out of a vuejs component and testing it locally?

Initially, I created a vuejs project as a test container using vue-cli. Next, I developed an npm package named "vue-npm-example" from a Vuejs component in my local environment and then imported it into the aforementioned testing project. Within the packag ...