GET method not working on specific route in ExpressJS - javascript

When I try to get data using /:user the function is not running inside the specific routing, can anyone figure me out what is the mistake here?
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const {accountSC,catalogSC} = require("./schema");
let dburl = **database url**
app.use(express.json());
mongoose.connect(dburl);
app.get("/catalog", async (req, res) => {
//some func inside it
});
app.get("/:catalog/:id", async (req, res) => {
//some func inside it
});
app.get("/:user", async (req, res) => {
//some func inside it
});

Basically your /catalog and /:user are the same because of the structure. :user value can be catalog also. So, try out different naming approaches of the routes (/info/:user).
Thank you.
update:
Try out this one.
app.get("/catalog", async (req, res) => {
//some func inside it
});
app.get("/catalog/:catalog/:id", async (req, res) => {
//some func inside it
});
app.get("/info/:user", async (req, res) => {
//some func inside it
});

Related

Express Middlewares execute their arguments, while JavaScript functions doesn't

I want to write an express middleware, I'm calling it express-stack-player.
What this middleware does is that it gives your middlewares access to the objects (req, res, next), by getting the benefit of the JavaScript scopes ex:
The following is a very simplified version of its code, which sums up its core job of it:
const stackPlayer = (stacks) => (req, res, next) => {
// #param stacks: function
const stacksValue = stacks(req, res, next);
for (middleware of stacksValue) {
middleware(req, res, next);
}
};
It used to work during my project which I'm working on until eventually, I discovered an unwanted behaviour by running the following test:
const express = require("express");
const app = express();
const setter = (req, res, next) => {
console.log("hello world");
req.a = {};
req.a.b = 1;
next();
};
const readSomething = (something) => (req, res, next) => {
console.log(something);
};
const stackPlayer = (stacks) => (req, res, next) => {
// #param stacks: function
const stacksValue = stacks(req, res, next);
for (middleware of stacksValue) {
middleware(req, res, next);
}
};
app.get(
"/",
stackPlayer((req, res, next) => [setter, readSomething(req.a.b)])
);
console.clear();
app.listen(4000, () => console.log("listening on port 4000"));
When I run npm start, it prints the following in the terminal just normally:
But when I request GET /, the following error prints out:
I was testing this JavaScript code in the browser to see its behavior:
const obj = {}
const setOnObj = () => {
obj.a = {}, obj.a.b = 1
}
const readSomething = (arg) => {
console.log(arg)
}
setOnObj()
readSomething(obj.a.b)
If you click on Run code snippet, the output will be 1. So why does my express-stack-player package have a different behavior?
By the way, the package is on npm, and it can be downloaded by running
npm i #samislam/switcher
In the past, I made a bigger package called switcher, but now I want to move the core logic of executing the middlewares into a separate package, and I'll call it express-stack-player (if the name would be available by then).

Node: Cannot acces to an endpoint

I have no idea about what is happend. I've developed a server who serves information through an API REST. I have defined several endpoints which works without any problem but the end points defined today doesn't work anyone of them.
The code of my router.js is:
import express from "express";
import {Result} from "../com/result";
import config from "../config";
import {getData, getPhotoFromGIATAServer} from "../com/functions";
import {XMLParser} from "fast-xml-parser";
import fs from "fs";
const router = express.Router();
router.post("/api", async (req, res) => {
});
router.post("/api/destinations", async (req, res) => {
});
router.post("/api/country", async (req, res) => {
});
router.post("/api/media", async (req, res) => {
});
router.post("/api/factsheet", async (req, res) => {
});
router.post("/api/texts", async (req, res) => {
});
router.post("/api/update", async (req, res) => {
});
router.post("/api/photo", async (req, res) => {
});
router.post("/api/update/photos", async (req, res) => {
//Doesn't work
});
router.post("/api/update/texts", async (req, res) => {
//Doesn't work
});
router.post("/api/update/factsheets", async (req, res) => {
//Doesn't work
});
module.exports.Router = router;
All the endpoints works fine except the last three ones. When I make a call to one of them I receive a 404 error.
As you can see, the domain and por in both cases are equals but one of them works and the other one not.
I don't understand anything. What is happend? What am I doing wrong?

Express.js main router working, but others routers on him not

I have the problem on routers. My main route /weather working, but others routers on him don't.
app.js
const express = require('express');
const weatherRoute = require('./back/routes/weatherRouter.js');
const app = express();
app.use(bodyParser.json());
app.disable('etag');
app.use('/weather', weatherRoute);
weatherRouter.js
const router = express.Router();
router.get('/', async (req, res) => {
try {
const wholeData = await WeatherInfo.find();
res.json(wholeData);
} catch (err) {
res.json({ message: err })
}
});
router.get('/now', (req, res) => {
res.send("ITS NOT WORKING");
});
module.exports = router;
the problem is that localhost:5000/weather working perfect, but when I want to use some other routers on that Route e.g. localhost:5000/weather/now that's not working
Any ideas what I'm doing wrong ?
UPDATED :
it works, when between those routers is no others routers.
e.g.
router.get('/', async (req, res) => {
//working
}
router.post('/:add', async (req, res) => {
//working
}
router.get('/now', async (req, res) => {
//doesnt work
}
If I move /now above /add router it works perfect. Can someone explain why is this happening ?
Define actual path in path section likerouter.post('/weather/now', (re, res) => {
//Handel re
}
I found the solution.
The routers position is matter. Reference to explanation
My last router didn't work, because another router already catched him.
app.get('/:add', function (req, res) {
// this will match all /a, /b .. including /new
res.end('done!');
});
app.get('/now', function (req, res) {
// this is never called
res.end('done!!');
});

How to pass values from a middleware to a route in Express.js?

const router = require('express').Router()
const loggerMiddleware = (req, res, next) => {
console.log(`${req.method} ${req.path}`)
req.locals.isLogged = true
next()
}
router.get('/color', loggerMiddleware, (req, res) => {
console.log(req.locals.isLogged)
res.send('#ff0000');
})
When I run the code above, Node compiler gives me a warning of TypeError: Cannot set property 'isLogged' of undefined. Where do I go wrong?
You need to put locals to res not req
const router = require('express').Router()
const loggerMiddleware = (req, res, next) => {
console.log(`${req.method} ${req.path}`)
res.locals.isLogged = true
next()
}
router.get('/color', loggerMiddleware, (req, res) => {
console.log(res.locals.isLogged)
res.send('#ff0000');
})
I am not familiar with how to pass data from a middleware to a route, but this looks like a plain javascript issue. It looks like req.locals is undefined. Start by checking if req.locals is undefined. If it is undefined, intialize it through req.locals = {}. Then set req.locals.isLogged = true.

Node JS async/await controller issue

I am trying to use an asynchronous function in my Node API controller, but am receiving an error from my 'error-handler' middleware.
TypeError: fn is not a function
at eval (webpack:///./app/middleware/errorHandler.js?:16:21)
It does not like my 'findAll' function exported from my controller, why is this not a function? Am I exporting the function correctly? Am I using async/await correctly? Do I need a polyfill for this? I understood that async/await was supported from Node v8. I am currently running Node v11.10 and Express v4.16.4.
Here is my routes file:
// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const errorHandler = require('../../middleware/errorHandler.js');
module.exports = app => {
const controller = require('../../controllers/controller.js');
app.get(`/collection`, verifyToken, errorHandler(controller.findAll));
}
Here is my controller:
// controller.js
exports.findAll = async (req, res) => {
const collections = await collection.find().populate('other');
res.send(collections);
};
Here is my middleware:
// errorHandler.js
module.exports = fn => {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
};
Any help is greatly appreciated.
Im not sure but is errorHandler expecting fn to be the error? If so, why is it called passing (req, res next)?
I use following structure:
Router
// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const controller = require('../../controllers/controller.js');
var router = express.Router()
router.route('/collection').get(
verifyToken,
controller.findAll
)
module.exports = router
Controller
// controller.js
const asyncUtil = fn =>
function asyncUtilWrap(req, res, next, ...args) {
const fnReturn = fn(req, res, next, ...args)
return Promise.resolve(fnReturn).catch(next)
}
module.exports = {
findAll: asyncUtil(async (req, res, next) => {
const collections = await collection.find().populate('other'); // you can do try/catch here if you want to handle the error here
res.send(collections);
};
Then Error Handler usually goes at bottom of app.js (but you can place it at bottom of your router):
// app.js
app.use(function(err, req, res, next) {
res.status(err.status || 500)
res.send(err.message)
})
I believe this is how I would do it if I understand you correctly:
// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const controller = require('../../controllers/controller.js');
module.exports = app => {
app.get(`/collection`, verifyToken, controller.findAll);
}
// controller.js
exports.findAll = async (req, res, next) => {
try {
const collections = await collection.find().populate('other');
res.send(collections);
} catch(err) {
console.log(err); // up to you what to do with the error
next();
}
};

Categories

Resources