Express4 app.get don't wait library call for continue - node.js

I have an express 4 node application with following.
My problem is app.get don't wait to finish exectuion of getAllFsRiver and return nothing.
How to do this?
in app.js
var api1 = require('./routes/api1.js');
app.use(api1) ;
in route/api1.js
*jslint node: true */
'use strict';
var express = require('express');
module.exports = express();
var app = module.exports;
var esclient = require('../lib/esclient') ;
/* GET api vers 1 . */
app.get('/api/1/settings/rivers/fs*', function (req, res) {
var allriver = esclient.getAllFsRiver() ;
console.log("route");
res.json(allriver);
Here res.json is called before esclient.getAllFsRiver has finish execution

My guess is that getAllFsRiver is asynchronous and probably takes a callback. You should pass a callback to the function and handle the response within the callback.
esclient.getAllFsRiver(function (err, json) {
if (err) {
return res.status(500).end();
}
res.json(json);
});

Sorry, I can't add comment. Could you add getAllFsRiver implementation to the question? Maybe it is an async call.

You have must write you route kind of:
*jslint node: true */
'use strict';
var express = require('express');
var router = express.Router();
router.get('/api/1/settings/rivers/fs*', function (req, res) {
var allriver = esclient.getAllFsRiver() ;
console.log("route");
res.json(allriver);
/* ... */
})
module.exports = router;
In you code you exporting from you route new express app, that wrong

adding a callback ti my function. Ok

Related

Flow of node.js routing when using separate controller and router

In my Node.js project I am using router file that imports controller files that have actual implementation of the methods. Like below.
app.js
'use strict';
var express = require('express');
var app = express();
var apiRoutes = express.Router();
routes.mainApi(apiRoutes);
app.use('', apiRoutes);
apiRoutes
'use strict';
var controller = require('../controller/apiController');
var uploadController = require('../controller/uploadController');
var fileUpload = require('express-fileupload');
module.exports.mainApi = function (apiRouter) {
apiRouter.post('/login', controller.login);
}
apiController
exports.login = function (req, res) {
// My code for login
};
I know when a api request comes then first app.js is executed. It further sends the request to apiRoutes as I called it in file. In apiRoutes when it finds
apiRouts.post(./login,controller.login) then it calls login function from controller. But I want to know that I am not passing req and res parameters anywhere in the login function then how they are being passed. Basically how this type of calling works.
Thanks in advance.
this function controller.login
as a callback parameter of r.post('path', callback)
and when controller.login is actual called by callback(request, response )
you will get req and res

Exporting a Mongoose connection that becomes available in an async callback?

I'm new to coding in Node.js and I've created a DB connection through mongoose, then exporting the database object into my main app.js file:
// db.js
var mongoose = require("mongoose");
var uri = /*The URL*/;
var db = mongoose.connect(uri, {
useMongoClient: true
});
exports.db = db;
Here I'm trying to use that DB connection to perform CRUD operations:
// app.js
var db = require('./db');
app.post('/', function (req, res) {
db.collection(/* … */); // throws error
});
The error is:
TypeError: db.collection is not a function
I think this is because that the call of connect in the db.js is asynchronous and the require in app.js is synchronous - so it'll be undefined when I execute db.collection?? How can Mongoose be used to avoid this error?
Goal: I want to be able to call db.collection.insertOne() within my app.js
I found a somewhat related topic but it doesn't use Mongoose, so I'm confused as to how to resolve this issue: How to export an object that only becomes available in an async callback?
Answering my own question:
It'll need a mongoose model in the app.js. So instead of doing db.collection in the main app.js, I ended up routing the CRUD operations to functions defined in the controller file.
//app.js
var app = express();
var router = express.Router();
app.use(router);
require("./Routes")(router);
router.get("/xxx", xxx.get);
Here are the routes:
//routes.js - takes care of routing URLs to the functions
var XXX = require('../xxx');
module.exports = function(router){
router.get('/XXX', XXX.get)
};
Here is the actual function:
//xxx.js - functions defined here
exports.get = function (req, res) {
XXX.getAll(req.body, function(err, result){
if (!err) {
return res.send(result); // Posting all the XXX
} else {
return res.send(err); // 500 error
}
});
};

how to create a nodeJS module with expressJS

I'm making a nodeJS module, and I want to use expressJS as a framework for it.
I'm trying to see, how I could go by, including a function inside and app.get(); and call it via another file, such as the actual app.
var express = require("express");
var app = express();
app.get("/", function (req, res) {
exports.type = function (text) {
console.log(req.ip);
console.log(text);
}
});
now when I use this, and i call it on the actual app like:
var web = require("directory_to_file");
var express = require("express");
var app = express();
var http = require("http").Server(app);
app.get("/", function (req, res) {
web.type("Hello, world");
});
http.listen(10022, function () {
console.log("server is up");
});
I get an error:
TypeError: Property 'type' of object #<Object> is not a function
anyone know a way to make it so I can call the function?
There are generally two things you want to export as a module - an API and a Middleware. The classic example of middleware is an authentication module. To do the middleware, just export the middleware. I tend to do a little more than that so I can configure the middleware later. Something along the lines of this:
module.exports = exports = function(config) {
// Do something with config here
return function(req, res, next) {
// your middleware here
};
};
You can then use your middleware in your main program like this:
var app = require('express')(),
mymodule = require('./mymodule');
var config = {}; // replace with whatever config you need
app.use(mymodule(config));
app.listen(process.env.PORT || 3000);
To implement an API, you will create a Router object, then attach your routes to the Router object. You can then "mount" your router in your main program. For example, you could have a file called 'myroutes.js' with the following contents:
var express = require('express'),
myroutes = express.Router();
myroutes.get('/foo', (req, res) => {
res.status(200).type('application/json').send({ myparam: 'foo' });
});
module.exports = exports = myroutes;
Have the following in your main program:
var app = require('express')(),
myroutes = require('./myroutes');
app.use('/api', require('./myroutes'));
app.listen(process.env.PORT || 3000);
Here, in 'myroutes.js', I'm defining a sub-route of /foo and then in the main program, I'm mounting that on /api - so I would access /api/foo to access that API.
In your directory_to_file you are only exporting on app.get('/') which will never be called.
You could add in your directory_to_file the following code
var express = require('express');
var router = express.Router();
router.get('/', function(req, server) {
console.log(req.ip);
});
module.exports = router;
And in your main file you could use app.use('/', web)
A short explanation:
You are creating a new express app / config in your directory_to_file file which won't be launched or used. So your app.get event won't be fired once.
That's why web.type is not a function. You are not exporting anything.
Use the way I provided. This is a commonly used method.
You could call the code I provided a "route". Create multiple routes / route files and include them in your main method.
Your code just looks confused. If I understand you correctly, what you are really trying to do (at least in Node/express terminology) is write your own middleware.
Express is designed with this in mind and it's pretty straightforward e.g.
ipLogger.js
module.exports = function(req, res, next) {
console.log(req.ip);
next();
}
app.js
var http = require("http")
, express = require("express");
, app = express()
, server = http.Server(app)
, ipLogger = require("./ipLogger.js");
app.use(ipLogger()); // log IP of all requests
// handle routes
server.listen(10022, function() {
console.log("server is up");
});

Move routes into files in Express.js

Say I have some routes (I have a lot more, but this should explain):
router.post('/post');
router.get('/post/:id');
router.get('/posts/:page?');
router.get('/search');
For the /post ones I know I could do something like
app.use('/post', postRoutes)
Where postRoutes is the actual post routes in another file. However, I'd like to group all post related routes into a postRoutes component (so /post and /posts), search into a search component and so on. Is there a way to do something like
router.use(postRoutes); // includes routes 1-3 above
router.use(searchRoutes); // only the 4th route above
And so on? That would let me keep the top level file much cleaner.
Yes it is simple. You can even make more nesting levels. I think it is good to separate routes, especially when you have dozens of routes.
in your first file (server.js)
app.use(require("./allpost"));
app.use(require("./allqueries"));
in allpost.js
var express = require('express');
var router = new express.Router();
router.post('/post', function (req, res) {
//your code
});
router.get('/post/:id', function (req, res) {
//your code
});
router.get('/posts/:page?', function (req, res) {
//your code
});
when you want more nesting
router.use(require("./deeper"));
or when you want use path part
router.use("/post2/", require("./messages/private"));
module.exports = router;
You could do that by creating a special route file. Here's an example of such file
module.exports = (function() {
var express = require('express');
var router = express.Router();
router.get("/:id", function (request, response, next) {
request.body.id = request.params["id"];
// Do something ...
});
router.post("/someRoute", function (request, response, next) {
// Do something ...
});
// And so on ...
return router;
})();
Next, in you server.js file, include it like this
app.use('/post', require('./routes/postRoutes'));
The problem was I was thinking about this wrong. First off, don't use singular and plural. It makes it a headache and also makes it hard for people to remember the API.
Once I used all plural I had a setup like this in my index.js file:
// The API routes all start with /api and we pass app here so we can have some
// sub routes inside of api
app.use('/api', require('./app/api')(app));
And then in my api/index.js
var express = require('express');
var router = express.Router({ mergeParams: true });
var routeInit = function (app) {
app.use('sessions', require('./sessions')(router));
app.use('users', require('./users')(router));
return router;
};
module.exports = routeInit;
You can see that I'm passing the router manually each time. Then finally:
var routeInit = function (router) {
router.post('/blah', function (req, res, next) {
// Do stuff
});
return router;
};
module.exports = routeInit;
This allowed me to nest routes infinitely deep.

Express-resource pass additional data from app.js to routes

I would like to pass additional data from app.js to express-resource routes and I have not figured out yet. How would you do that? Note that I'm using express-resource
// app.js
var myAddOnData = 'abc';
app.resource('users', './routes/user');
// user.js
exports.index = function (req, res) {
console.log(myAddOnData);
};
Thanks
These are the three approaches I can think of. Without the little I know about your specific problem, it sounds like middleware might be the way to do it.
With a global app variable
Create a value using app.set in app.js and then retrieve it using app.get in user.js.
Using a module
Store the information in an isolated module, then require() as needed. If this is running across multiple instances, you'd obviously want to store the values to disk as opposed to in memory.
// keystore.js
// -----------
module.exports.set = function(id, val) { /* ... */ };
module.exports.get = function(id) { /* ... */ };
// app.js
// -----------
var ks = require('./keystore');
ks.set = function("userInfo", "abc");
module.exports.get = function(id) { /* ... */ };
// user.js
// -----------
var ks = require('./keystore');
ks.get = function("userInfo", "abc");
(Maybe check out pot?)
Using Middleware
Use custom middleware to attach data to the request object which can then be accessed later in the route handlers.
//app.js
//------
var express = require('express')
, cookieSessions = require('./cookie-sessions');
var app = express();
app.use(express.cookieParser('manny is cool'));
app.use(cookieSessions('sid'));
// ...
//cookie-sessions.js
//------------------
module.exports = function(name) {
return function(req, res, next) {
req.session = req.signedCookies[name] || {};
res.on('header', function(){
res.signedCookie(name, req.session, { signed: true });
});
next();
}
}
via https://gist.github.com/visionmedia/1491756

Resources