Вызов функции с req, res params

#javascript #node.js #express

#javascript #node.js #выразить

Вопрос:

Я создаю API для NodeJS с помощью Express. У меня есть функция в продуктах схемы, которая возвращает продукт по идентификатору. Сигнатура этой функции выглядит следующим образом:

 let getProductsById = (req, res) => {
    let id = req.params.id;
    Producto.findById(id)
        .populate('categoria')
        .populate('marca')
        .exec((err, producto) => {
            if (err) {
                return res.status(500).json({
                    ok: false,
                    error: err
                });
            }
            if (!producto) {
                return res.status(400).json({
                    ok: false,
                    error: {
                        message: 'Producto no encontrado'
                    }
                });
            }
            productoResponse = {
                _id: producto._id,
                codigo: producto.codigo,
                descripcion: producto.descripcion,
                nombre: producto.nombre,
                precioCosto: producto.precioCosto,
                precioVenta: producto.precioVenta,
                categoria: {
                    _id: producto.categoria._id,
                    nombre: producto.categoria.nombre
                },
                marca: {
                    _id: producto.marca._id,
                    nombre: producto.marca.nombre
                }
            }
            res.json({
                ok: true,
                producto: productoResponse
            });
        });
}
  

Если вы не хотите читать всю функцию целиком, в resume this верните объект с некоторой информацией в нем.

Я вызываю эту функцию в маршрутизаторе следующим образом:

 app.get('/producto/:id', function(req, res) {
    getProductsById(req, res);
});
  

Это работает нормально, но я хочу в другой схеме (Cart) вызвать эту функцию для получения продукта. В службе Cart у меня есть эта функция:

 let addCart = (req, res) => {
    let body = req.body;
    let cart = new Cart({
        user: body.user,
        products: body.products,
        pay: body.pay,
        address: body.address,
        phone: body.phone,
        moreInfo: body.moreInfo,
        total: body.total
    });
    cart.products.forEach(product => {
        console.log(product._id);
        req.params.id = product._id;
        let productX = getProductsById(req,res);
    });
}
  

Но это не работает, у меня ошибка, которая гласит:

 events.js:288
      throw er; // Unhandled 'error' event
      ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:526:11)
    at ServerResponse.header (C:UsersNachoDesktopnode07-restservernode_modulesexpresslibresponse.js:771:10)
    at ServerResponse.send (C:UsersNachoDesktopnode07-restservernode_modulesexpresslibresponse.js:170:12)
    at ServerResponse.json (C:UsersNachoDesktopnode07-restservernode_modulesexpresslibresponse.js:267:15)
    at C:UsersNachoDesktopnode07-restserverserverservicesproductService.js:57:40
    at C:UsersNachoDesktopnode07-restservernode_modulesmongooselibmodel.js:4832:16
    at C:UsersNachoDesktopnode07-restservernode_modulesmongooselibhelperspromiseOrCallback.js:24:16
    at C:UsersNachoDesktopnode07-restservernode_modulesmongooselibmodel.js:4855:21
    at C:UsersNachoDesktopnode07-restservernode_modulesmongooselibquery.js:4407:11
    at C:UsersNachoDesktopnode07-restservernode_moduleskareemindex.js:135:16
    at processTicksAndRejections (internal/process/task_queues.js:79:11)
Emitted 'error' event on Function instance at:
    at C:UsersNachoDesktopnode07-restservernode_modulesmongooselibmodel.js:4834:13
    at C:UsersNachoDesktopnode07-restservernode_modulesmongooselibhelperspromiseOrCallback.js:24:16
    [... lines matching original stack trace ...]
    at processTicksAndRejections (internal/process/task_queues.js:79:11) {
  code: 'ERR_HTTP_HEADERS_SENT'
}
  

Как я могу решить эту проблему? Ty.

Я решаю поступить таким образом (не следовать моим шагам плохо, и мне нужно реструктурировать код)

 carrito.productos.forEach(producto => {
        console.log(producto._id);
        let id = producto._id;
        Producto.findById(id)
        .exec((err, productoObtenido) => {
            if (err) {
                return false;
            }
            if (!productoObtenido) {
                return false;
            }
            producto.precioVenta = productoObtenido.precioVenta;
        });
    });
  

Ответ №1:

Проблема здесь

 cart.products.forEach(product => {
    console.log(product._id);
    req.params.id = product._id;
    let productX = getProductsById(req,res);
});
  

Итак, вы вызываете res.send несколько раз из getProductsById

Они выражают отказ от этого.

Комментарии:

1. Вы, вероятно, подумаете, что я груб, но ваш код — просто мусор. Ничего хорошего, ужасный дизайн. И это абсолютно нормально, поскольку вы пытаетесь одновременно изучать express, mongo и API. Довольно сложно. Следуйте некоторым руководствам по Express Mongo вместо того, чтобы пытаться разобраться в этом самостоятельно, это сэкономит вам много времени. Затем вы попытаетесь следовать своим собственным путем.

Ответ №2:

Я думаю, вам следует реструктурировать свое приложение. Переместите свою фактическую бизнес-логику на уровень, лежащий за обработкой запросов и ответов. Таким образом, вы можете повторно использовать сервисы / функции без передачи объектов запроса и ответа, что усложняет написание и понимание вашего кода.