Correct use of express in Node js - node.js

const express = require('express');
const app = express();
app.set('view engine', 'ejs');
app.listen(10000);
function function_a(inp)
{
var tmp_var = inp;
console.log(tmp_var)
//10 - the first time
//20 - the second time
app.get('/pageno1', (req, res) => {
res.redirect('...');
//..
console.log(tmp_var) //10 - on both calls
//..
});
}
function start(/* .. */)
{
//...
function_a(10);
function_a(20);
}
Suppose that I have two functions that simplified look something like the above. My issue is that the tmp_var holds the same value on both calls inside the app.get('/pageno1') even though I pass a different value.
Two points I would like to bring your attention to;
a) I dont use next(); (I am not sure if thats the issue),
b) I dont have a 'default' page (app.get('/', ...)) because I didnt need it (kinda weird, but thats my case.) I dont mind adding one, if thats the issue.
EDIT:
What is the expected end result: Get the URL parameters passed onto a URL and (eg: example.com/route?=<...>) and redirect the user to a page. After that is done in my code, in another function, use a stored variable and do some other things, using the parameters gotten from the URL and the stored variable. Wait for next GET request.
What I tried:
app.get('/pageno1', (req, res, next) => {
res.redirect('https://..');
//when that is done, move to another function
//here comes the issue (that other function needs the stored variable)
//and although its not needed inside `app.get` I need to pass it to the
//function after thats done.
function_A(param, req.query);
});
function_A(inp1, inp2)
{
//do some things
}
If that can be done using native HTTPS module, I don't mind not using express.
Lastly in case its not clear, I want to pass the local variable in the other function (function_A). So not necessarily inside the /pageno1 request. But, AFTER the pageno1 request is done, I need both the local variable and the req from the request to call the function_A.
If you need better explanation in anything, feel free to ask!

Related

My exports function isn't working because of error "TypeError: Cannot read properties of undefined (reading 'send')"

I'm new to the server side of programming and I can't figure out why the terminal is telling me that the send function in express isn't defined. I've tried putting express in the document, and I've tried different formats for the function, but I still can't figure it out. (It's complaining about the "getgameData" function)
I changed the send function thinking that it might be that you can't use the send function, but it turns out that no functions work there, but when I just try and return any other data structure, the terminal is still upset. Then, I tried restructuring the function and it still didn't work.
/////////////////////////////////////////////////////////////////////////////////////////
var gameData = require('../models/gameData.js');
var player = "ed";
exports.updateGame = function(res,req){
gameData.gameData = req.data;
}
exports.resetGame = function(){
res.send(gameData.gameData);
}
exports.getGameData = function(res,req){
gameData.gameData.playerNames.me = player;
res.setHeader('Content-Type','text/plain');
res.send(gameData.gameData.playerNames.me);
}
//////////////////////////////////////////////////////////////////////////////////////
** The app that connects the client side and the server side
//////////////////////////////////////////////////////////////////////////////////////
//all required js for Part 2
var game = require('./controllers/gameController');
var setup = require('./controllers/setupController');
var topTen = require('./controllers/topTenController');
// all routes
// game data routes
app.route('/api/gameData')
.get(game.getGameData())
.patch(game.updateGame)
Pass the callback function into the get(), not the function, executed. Get will pass in req, res, next to your callback and then execute it.
// all routes
// game data routes
app.route('/api/gameData')
.get(game.getGameData)
.patch(game.updateGame)
I also just noticed that you have your middleware functions arguments in the wrong order. The order is: req, res, next. Reference here.

When testing an ExpressJS route using mocha+sinon, how do you "stub" a function that's local to the route?

So in one file, I have this route defined:
router.post('/', security.authenticate, function(req, res, next) {
//Doing prep stuff
//Do database work (<< this is what im really testing for)
//Calling another work function.
createFormUser(req.body, (ret) => {
return res.json(ret.createdUser);
});
});
followed by this function:
var createFormUser = (ourUser, call) => {
// does a bunch of misc work and creation for another database
// unrelated to current tests.
}
I want to to test this route. Normally, I would just create a sandbox instance of the database so that it can do whatever it wants, make an http request to the route in the test, and finally do expects() in the return from that http call.
However, I don't want the "createFormUser" function to be called, because 1) it does some fancy shit that's really hard to contain for this test 2) I will be testing it elsewhere.
In a normal test I would at this point use sinon to stub the function. But in this case I don't actually have an object reference, since this is all done through HTTP requests to server that mocha spools up when testing.
So my question is the same as the title, how can stub/replace/ignore/etc this method so it doesn't get called during the test?
As stated by #DavidKnipe, all I had to do was export the methods via:
module.exports.createFormUser = (ourUser, call) => { ... }
And was able to both test the method individually and prevent it's execution via a sinon.stub.

Override express route handler

I'm trying to redefine a express route handler
I have something like
var x = {
handle: function(req, res){
res.send("first");
}
}
app.post("/handle", x.handle);
setTimeout(function(){
x.handle = function(req, res){
res.send("second");
}
}, 2000)
but this doesn't change the way that route handles requests.
How can I achieve something like this?
A simplest fix is to ensure x.handle is always retrieved. In your approach, the function reference is retrieved once, when you attach it but then when you set the reference to point to another function, the post handler still points to the old one.
Attach then
app.post("/handle", (req, res) => x.handle(req, res) );
This method always asks x for current value of the handle method and you are free to reattach it to anything you want.
why it doesn't work
when you pass x.handle into a method, as a callback, you are not passing a reference to x at all. you are only passing handle around.
later, when you change x.handle, you are changing the handle method for x as expected. but, the previous reference to x.handle as a parameter to your post method is unchanged, because this call to post knows nothing about x. it only knows about the handle method that you passed in.
how to fix it
there are a lot of ways to fix this, depending on how you really want to handle things.
if you just need a timeout, then something like this would work:
var count = 1;
app.post("/handle", function(req, res){
if (count === 1){
setTimeout(function(){
count += 1;
}, 2000);
// do the first thing here
} else {
// do the second thing here
}
});
if you don't need the timeout, you could just increment the count
again, there are a lot of ways to do this... but you will have to include the logic of deciding which one to do, inside of the route handler function directly.

Express.js - ASP.NET-like MVC Routing

I'm trying to setup an MVC architecture for Express. What I am trying to accomplish is a routing mechanism close to ASP.NET's. For example for the following route:
/users/detail/1
express should call a module under controllers directory named users.js. Within the users.js module is a function named detail. And within the function, I can simply get the request parameter to get the id of the user.
My idea is to extract the users and map it to a users.js file using a simple require statement. But how can I tell express to call details() function by simply extracting the action part of the route which is 'detail' in the above example. I can use eval() but I am hearing that it's not a safe thing to do? Thanks in advance.
In browser-side javascript, you can typically do the following
function a () { console.log('called a');
window['a'](); // called a
You can do similar in node by replacing window with global such as
function a () { console.log('called a');
global['a'](); // called a
However, if you are pulling this function in from another file, it will be little different. Let's assume that you have the following file a_module.js:
exports.a = function () { console.log('a called'); }
And then in you're main file, you can do the following:
var a_mod = require('./a_module.js');
a_mod['a'](); // a called

Possible to create many app.get calls with express.js through for loop?

this is my first post so thanks in advance for the help :)
I'm trying to make my main.js file and to make things easier I want to do something like this:
var pages = {
"/profile":{"page":"My Profile","loc":"./contentPages/profile"},
...
...
...
};
for (var item in pages) {
app.get(item, function(req, res){
if(req.session.user_id == null){
res.redirect('/');
return;
}
res.render(pages[item].loc, {
title:pages[item].page,
thisPage:pages[item].page
});
});
}
right now no matter what happens whatever I have last in the dictionary is the the page which is always rendered. Is there a way to do something like this or must I write out every page I want to create?
Thanks so much!
The problem is that all the closures created by function(req, res) refer to the same variable (item) so they all use whatever value it has when they're called rather than what it had when they were created, and that's going to be the last one.
Most straightforward workaround is to create the closures with a helper function:
function makeHandler(item) {
return function(req, res) {
// copy body of handler function here
};
}
and then replace the body of your loop with:
app.get(item, makeHandler(item));
Now each handler gets its own private copy of item which always retains the value it had when it was created.
You could also use an immediate function invocation to create the closures, but that would make the code look a little more cluttered.

Resources