0

I have the following lines of code:

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

// ... defining the routes, app.get('/api/users', (req, res, next)=>{ }) ...etc

app.listen(3000, ()=> console.log('Listening on port 3000...'))

module.exports = app
  • I want to be able to read the request object outside an express middleware.

I have another file called mongoose_models.js, inside that file, I don't have the access to the express middleware arguments (req, res, next).

And the only option I have for reading the request body from that file is to import the app and somehow read the request Object.

NodeJs is event-driven, so there must be a way somehow to do so, for instance, inside the file mongoose_models.js I would have maybe something like this code:

// mongoose_models.js
// ... some code
const app = require('../app.js')

app.on('request', (req)=>{
// here I have the request
})

or maybe if express supports:

// mongoose_models.js
// ... some code
const { req } = require('express')

console.log(req.body) // ? maybe something like that ?

or maybe if express supports too:

// mongoose_models.js
// ... some code
const app = require('../app.js')

app.onRequest((req, res) => {
// here I have the access to the request object
})

Is there a way to reach the request object without having to be inside an express middleware in NodeJS?


edit:

Some of you asked me to provide the source code, unfortunately, I wanted to provide a stackblitz or code sandbox instance, but I didn't know how to set up the connections to the database.

Anyway, the following is the file structure of the sample project: file structure

app.js file (full code):

const express = require('express')
const app = express()
const mongoose = require('mongoose')

const RoomModel = require('./mongoose_models')

app.use((req, res, next) => {
  // this middleware is the "protect" middleware, it validates a JWT (JSON web token), decodes it, and then stores the user it finds to the req object:
  // .... etc some code

  // decode the JWT .. some code
  // find the user in the DB const userDoc = await UserModel.findOne({ _id: decodedJWT.id )})
  const userDoc = {
    id: 'abc-123-edf-cds-123-321-qu5-eu4-dc9-182',
    name: 'Murat',
    // and some other fields ... etc
  }
  req.$loggedInUser = userDoc
})

app.get('/rooms', async(req, res, next) => {
  const docs = await RoomModel.find({})

  res.status(200).json({
    message: 'here are all the rooms',
    results: docs.length,
    data: docs,
  })
})

app.post('/rooms', async(req, res, next) => {
  const doc = await RoomModel.create(req.body)
  res.status(201).json({
    message: 'the new room which got created:',
    data: doc,
  })
})

// connecting to the database:
mongoose.connect(
  'mongodb+srv://USERNAME:PASSWORD@YOUR_CLUSTER.mongodb.net/?retryWrites=true&w=majority'
)

// starting the HTTP service:
app.listen(3000, () => console.log('app listening on port 3000...'))

mongoose_models.js file (full code):

const mongoose = require('mongoose')

const roomSchema = new mongoose.Schema({
  name: String,
  by: mongoose.Schema.ObjectId,
})

roomSchema.pre('save', function(next) {
  // Here I want to make the by field be the req.$loggedInUser.id but I can't because I have no way to read the request object
  const doc = this
  // doc.by = req.$loggedInUser.id // < -----  HERE, I can't reach the req object
  next()
})

const RoomModel = mongoose.model('Room', roomSchema, 'rooms')

module.exports = RoomModel
Normal
  • 1,616
  • 15
  • 39
  • "*the only option I have for reading the request body from that file is to import the app and somehow read the request Object.*" - no. The other (much better) option is to simply pass the request object as an argument when your middlewares call the `mongoose_models` methods – Bergi Jul 04 '22 at 15:48
  • Please show us the code that calls your models methods, as well as the code in the models that wants to use the request. – Bergi Jul 04 '22 at 15:49
  • 2
    This is an XY problem. You're describing an issue with some solution you're pursuing, but not describing the fundamental problem you are really trying to solve. We can help you better if you describe the fundamental problem. The `req` object is not available globally as there can be many `req` objects in flight at the same time. Usually one just passes it as a function argument to whatever code needs it. – jfriend00 Jul 04 '22 at 15:56
  • Please check the express routing documentation https://expressjs.com/en/guide/routing.html We follow MVC pattern for our project, so we create a separate routes, models and controllers. How you handle the business logic, again depends on you. – Ashish kushwaha Jul 04 '22 at 16:00
  • okay I'm updating my question to provide a real-world example – Normal Jul 04 '22 at 16:02
  • i dont know what oyu want to achive, but by just reading this question i guess you doing something wrong – bill.gates Jul 04 '22 at 16:03
  • @bill.gates no, just a minute, I'll provide the example – Normal Jul 04 '22 at 16:23
  • 1
    Thanks for the edit. Yes, there's no way to access this data in the `preSave` hook, and you shouldn't try. Instead, just call `RoomModel.create({...req.body, by: req.$loggedInUser.id})` instead of `RoomModel.create(req.body)`. – Bergi Jul 04 '22 at 17:14

1 Answers1

3

NodeJS is event driven, so there must be a way somehow to do so, for instance, inside the file mongoose_models.js I would have maybe something like this code:

// mongoose_models.js
// ... some code
const app = require('../app.js')

app.on('request', (req)=>{
// here I have the request
})

This approach is, essentially, middleware. So write is as middleware.

const myMiddleware = (req, res, next) => {
    // here you have the request
    next(); // go to next middleware
}

module.exports = myMiddleware

Attaching something to listen for requests is done with use (for non-method specific functions) and post, get, etc. There is no on method or onRequest method.


// mongoose_models.js
// ... some code
const { req } = require('express')

console.log(req.body) // ? maybe something like that ?

The request object doesn't exist until the client makes a request to the server.

You get a new request object each time a request is made.

The server might be handling multiple requests at the same time.

So no, you can't do anything like that.


Is there a way to reach the request object without having to be inside an express middleware in NodeJS?

No.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335