'Load plugin after another fastify

I'm currently working on an api where I autoload my plugins but I would like to add global hooks on all routes. What I'm currently doing is I load all my plugins and after I load my middlewares but I have a problem I'm trying to use mongoClient created by fastify-mongo but I always end up with the error mongo is not defined.

When I'm using it on my controller everything works i thinks I get this error because the plugin is not fully loaded, I did find .ready but it doesn't work

plugin/mongo.js

import fp from 'fastify-plugin';
import mongoPl from '@fastify/mongodb';

async function mongo(fastify, opts) {
  fastify.register(mongoPl, {
    forceClose: true,
    url: 'mongodb://mongo:27017'
  });

}
export default fp(mongo, {
  name: 'mongo'
});

libs/middleware

import fp from "fastify-plugin";

async function hooks(fastify, opts) {
  fastify.addHook('onRequest', (req, res, done) => {

    // Inject mongo client
    mongoClient(req);

    done();
  });

}

async function mongoClient(req){
  try {
    req.db = this.mongo.client.db('db-name');
  }catch (e) {
    console.error(e);
  }
}

export default fp(hooks, {
  name: 'hooksMiddleware'
});

app.js

app.register(AutoLoad, {
  dir: join(import.meta.url, 'plugins'),
  options: Object.assign({})
}).after(() => {
  app.register(hooksMiddleware, {});
});


Solution 1:[1]

Your setup looks good, but the this context in mongoClient function is undefined.

Here some fixes:

async function hooks(fastify, opts) {
  fastify.addHook('onRequest', (req, res, done) => {

    // Inject mongo client
    mongoClient.call(fastify, req);

    done();
  });

}

Or:

async function hooks(fastify, opts) {

  // NOTE: I changed from arrow to an anonymous function
  fastify.addHook('onRequest', function (req, res, done) {

    // Inject mongo client
    mongoClient.call(this, req);

    done();
  });

}

You need to know:

  • the this context is set only on those named function that you provide to Fastify. The mongoClient function is just a function outside the Fastify's control
  • the this context cannot be set for arrow function. (opinion) I will never stop to say: use arrow function only for 1-line function, otherwise named function are always the best choice (better stack tracing, more readable)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 James Sumners