Cuando ejecuté mi código de esta manera, estaba teniendo errores como castError: cast to object failed for value new
app.get("/products/:id", async (req, res) => { const { id } = req.params; const product = await Product.findById(id); res.render('products/show', { product }); }); app.get('/products/new', (req, res) => { res.render("products/new"); });pero cuando cambié el formato de esta manera, el código se ejecutaba normalmente en mi máquina local.
app.get('/products/new', (req, res) => { res.render("products/new"); }); app.get("/products/:id", async (req, res) => { const { id } = req.params; const product = await Product.findById(id); res.render('products/show', { product }); });¿Cuál podría ser el problema? Es como resultado de mis parámetros de ruta o si el pedido cuenta. No entiendo, ya que estoy empezando a aprender express.js.
app.get("/products/:id", async (req, res) => { const { id } = req.params; const product = await Product.findById(id); res.render('products/show', { product }); }); app.get('/products/new', (req, res) => { res.render("products/new"); }); En el formato anterior, la ruta sobre la new ruta incluye un parámetro de ruta :id . Express coincide con todo lo que viene después de /products como si fuera el parámetro de ruta :id , es por eso que en el formato anterior obtuvo un error.
Para este, express sabe que si lo que viene después de /products/ es new , ejecutará el código dentro de app.get('/products/new', callback:
app.get('/products/new', (req, res) => { res.render("products/new"); }); app.get("/products/:id", async (req, res) => { const { id } = req.params; const product = await Product.findById(id); res.render('products/show', { product }); });Las rutas se evalúan en el orden en que se definen, y tampoco el aspecto que podría tener una id .
Supongamos que tiene una solicitud que va a /products/new
Cuando tu código se ve así:
app.get("/products/:id", async (req, res) => { const { id } = req.params; const product = await Product.findById(id); res.render('products/show', { product }); }); app.get('/products/new', (req, res) => { res.render("products/new"); }); La primera ruta declarada es "/products/:id" , que es una coincidencia y req.params.id será igual a "new" . Debido a que hubo una coincidencia, ni siquiera mirará las rutas que se declararon después.
* edite cómo podría tener el "/products/:id" en primer lugar y seguir funcionando de la manera que desea, probablemente no sea el mejor, pero es un ejemplo del caso de uso para el next parámetro
app.get("/products/:id", async (req, res, next) => { const { id } = req.params; if (id === 'new') { next(); return; // important to remember, without it the code below will also fire } const product = await Product.findById(id); res.render('products/show', { product }); }); app.get('/products/new', (req, res) => { res.render("products/new"); });En este caso el orden importa. Si coloca la ruta con el parámetro primero ( /products/:id ), tratará cualquier ruta que comience con /products/ como una ruta param. Por lo tanto, la ruta a continuación se tratará como una llamada de API de productos con una identificación igual a new .
app.get('/products/new', (req, res) => { res.render("products/new"); });Puede arreglar esto poniendo su ruta param después de la nueva ruta.
app.get('/products/new', (req, res) => { res.render("products/new"); }); app.get("/products/:id", async (req, res) => { const { id } = req.params; const product = await Product.findById(id); res.render('products/show', { product }); });