Injecting Dependencies Into ExpressJS Routes Middleware

Hey there! I'm currently working on injecting some dependencies into an expressjs route middleware.

Usually, in your main application, you would typically do something like this:

const express = require('express');
const userRouter = require('./routes/users.js');
const app = express();
app.use('/users', userRouter);

Then, in your users.js file, you might have something similar to this:

const express = require('express');
const router = express.Router()
router.post('/user', function (req, res, next) {...}
router.get('/user/:id', function (req, res, next) {...}
router.put('/user/:id', function (req, res, next) {...}
router.delete('/user/:id', function (req, res, next) {...}

However, I'm interested in passing some dependencies, like a service URL, and I'm not finding clear instructions on how to accomplish this based on the documentation. I was thinking of something like this:

const express = require('express');

function userRoutes(options) {
    const router = express.Router();

    router.post('/user', function (req, res, next) {...}
    router.get('/user/:id', function (req, res, next) {...}
    router.put('/user/:id', function (req, res, next) {...}
    router.delete('/user/:id', function (req, res, next) {...}

    return router
}

module.exports.userRoutes = userRoutes;

Then, in my main application, I would use it like this:

const userRouter = require('./routes/users.js');
const app = express();
app.use('/users', userRouter.userRoutes(options));

However, when I try to do this, I encounter the following error:

Users/jm/Private/Projects/api-gateway/node_modules/express/lib/router/index.js:458
  throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
  ^

TypeError: Router.use() requires a middleware function but got a undefined
at Function.use (/Users/jm/Private/Projects/api-gateway/node_modules/express/lib/router/index.js:458:13)
at EventEmitter.<anonymous> (/Users/jm/Private/Projects/api-gateway/node_modules/express/lib/application.js:220:21)
at Array.forEach (native)
at EventEmitter.use (/Users/jm/Private/Projects/api-gateway/node_modules/express/lib/application.js:217:7)
at Object.<anonymous> (/Users/jm/Private/Projects/api-gateway/app.js:28:5)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)

If you have any suggestions or solutions, they would be greatly appreciated.

Answer №1

After testing out your provided code, I can confirm that it is working as expected on my end. Here are the files I used for reference:

package.json:

{
  "name": "solution",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.16.4"
  }
}

index.js

const express = require('express');
const http = require('http');

const userRouter = require('./routes/users.js');
const app = express();
const options = {};
app.use('/users', userRouter.userRoutes(options));

const server = http.createServer(app);
server.listen(3000);
console.log('listening on port 3000');

routes/users.js

const express = require('express');

function userRoutes(options) {
    const router = express.Router();

    router.post('/user', function (req, res, next) {res.json({done:true})})
    router.get('/user/:id', function (req, res, next) {res.json({done:true})})
    router.put('/user/:id', function (req, res, next) {res.json({done:true})})
    router.delete('/user/:id', function (req, res, next) {res.json({done:true})})

    return router
}

module.exports.userRoutes = userRoutes;

Upon executing the npm start command, the server successfully started and began listening on port 3000.

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

Monitor the execution of JavaScript callbacks without the need for layering functions

Currently, I am developing a function that involves multiple database calls and needs to store their results in an array before triggering a callback. Let me share some pseudocode for better understanding: function getData (array, callback) { var resu ...

Slider handle for Material UI in React component reaches the range value

In my application, I am using a range slider component from material-UI. The main page displays a data table with the fields: id, name, current price, new price. The current price for each item is fixed, but the new price will be determined based on the s ...

What could be preventing my Express error handler from being invoked after running lint on my code?

I'm currently working on an Express app that features a custom error handler. The code for the error handler is as follows: app.use((err: Error, _req: express.Request, res: express.Response) => { console.log(err) // ...send back a well formatt ...

Displaying Dynamic Content in React Table Rows Based on Conditions

I'm populating a table with multiple rows using props. If a returned prop is an empty string "" , I want to exclude that row from rendering. <Table.Body> <Table.Row> <Table.Cell>Producer</Table.Cell> ...

Tips for triggering a sound only when transitioning from a true to false value for the first time

I have data for individuals that includes a dynamically changing boolean value. This value can be true or false, and it updates automatically. The webpage fetches the data every 5 seconds and displays it. If the value for any person is false, a sound is p ...

Maintain query parameters in Angular6 while routing with canActivate

When using Auth guard to verify login status and redirecting to the login page if a user is not logged in, there seems to be an issue with losing all query parameters during the redirection process. I attempted to preserve the query params by adding { qu ...

Giant Slide - navigate directly to a particular slide using a link

Hey there, I am currently working on incorporating the Superslide slider for fullscreen images in my website. My goal is to have a mostly text-free site where users can navigate through the images using the main menu or jump to a specific image within the ...

Tips for efficiently exporting and handling data from a customizable table

I recently discovered an editable table feature on https://codepen.io/ashblue/pen/mCtuA While the editable table works perfectly for me, I have encountered a challenge when cloning the table and exporting its data. Below is the code snippet: // JavaScr ...

Error occurs in console when using .getJSON with undefined JSON, but does not happen when using embedded data

Can someone help me understand why I'm getting an 'undefined' response when I use console.log(tooltipValues), but there's no issue with console.log(tooltipJSON). I've noticed that when I embed the data directly in my JS code, ever ...

Utilize the onClick event to access a method from a parent component in React

Looking for guidance on accessing a parent component's method in React using a child component? While props can achieve this, I'm exploring the option of triggering it with an onClick event, which seems to be causing issues. Here's a simple ...

The app's connection issue persists as the SDK initialization has exceeded the time limit

We are currently facing an issue when trying to publish a new manifest for our app in the store. The Microsoft team in India is encountering an error message that says "There is a problem reaching the app" during validation. It's worth noting that th ...

On the first load, Next.js retrieves a token from an API and saves it for later use

Currently working on an application with next.js, the challenge lies in retrieving a guest token from an API and storing it in a cookie for use throughout the entire application. My goal is to have this token set in the cookie before any page is loaded. H ...

Using JavaScript, you can manipulate the position of a line on a canvas to

I want to create a feature where users can manipulate lines on a canvas by skewing them. This means they would be able to drag one end point of the line to a desired point on the same x-axis using JavaScript and HTML5 canvas. Can someone please provide g ...

Guide to building a nested React component

My custom dropdown component requires 2 props: trigger (to activate the dropdown) list (content to display in the dropdown) Below is the implementation of my component: import { useLayer } from "react-laag"; import { ReactElement, useState } fr ...

What is the method for accessing a map that has been set in a separate component?

My current setup involves utilizing a Leaflet map with vue2leaflet. The process I follow is quite standard: I import a list of places from a REST Api in the app store (vuex) Following that, during map initialization, the markers are created using the in ...

jQuery mobile not recognizing the ID we specified

I am in the process of developing an audio application. My goal is to change the id of the Play button dynamically to "paused" when it is clicked. However, despite my efforts, clicking on the "paused" button does not pause the audio as intended. $(&ap ...

In certain Express app files, the use of Sequelize modules may result in a return value of undefined

Objective - To implement a middleware-like callback in userHandler located in util.js for certain express routes in an express app, created using express-generator and sequelize-cli. Expected Outcome - Utilize the user model successfully in routes and use ...

Confirm before closing the window

How can I get this code to function properly and show a confirmation alert after the user clicks on a button? This is essentially an "exit website button". The confirmation pop-up will have: If "OK" is clicked > the current window will close; If ...

How to automatically insert a comma into numbers as you type in Vue.js

I am trying to insert separators in my numbers as I type, but for some reason it is not working. Sample Code <el-input-number v-model="form.qty" style="width: 100%;" id="test" placeholder="Quantity" controls-position="right" v-on:keyup="handleChange" ...

Utilize Node JS to assign variables to HTML form inputs

Can anyone help me with storing HTML form inputs in variables using Node JS? I'm having trouble getting it to work properly. Below is the HTML form snippet: <form action="localhost:8080/api/aa" method="post"> <input id="host" type="text ...