How to use static variable in node js? - node.js

I am try to load country names and want to save them in static variable. So that I do not hit in my database again and again.
I am using express Js.
Please suggest me How can i load country name in optimize ways

In node.js, modules are cached after the first time they are loaded. Every call to import/require will retrieve exactly the same object.
A good way to achieve this is:
app.js
var app = require('express')(),
server = require('http').createServer(app);
var lookup=require('./lookup.js');
server.listen(80, function() {
//Just one init call
lookup.callToDb(function(){
console.log('ready to go!');
});
});
lookup.js
callToDb(function (country){
module.exports=country;
});
and wherever you require:
model.js
var countryLookup= require('./lookup.js');

Related

Small api on node.js

maybe someone have example for creating small API on node.js
Example, i have function this function will return string
I need call this string from postman or inside any another project with http.
What better for create this API?
Maybe someone know good guide? I worked before with node.js only like web-server
It is best practice that building API's in nodejs with express.Here is a code in which function returns a string. You need to export it. And require the file that contains exported value in your project file with the file path. Here is my function code where I am returning a string value. func.js
var string;
function myfunc(param,callback){
var str="hello";
callback(null,str);
}
myfunc('aaa',function(err,result){
if(err){
console.log(err);
}
else{
exports.string=result;
}
});
Here is my routes file and here I am calling the string from func.js and I named this file as str.js
var http = require('http');
var express = require('express');
var main = require('./func.js');//path of file
var org = main.string;
var app = express();
app.get('/str',function(req,res){
console.log(org);
res.send(org);
});
app.listen(3000,function(){
console.log("Server listening on 3000");
});
Run the code as node str.js and in postman run the url as http://localhost:3000/str and you can see the returned string in both response and in terminal.
Hope this helps...
This tutorial shows you how to build an API in Node.js with Express.
EDIT: You can skip the database part if you don't need it.

NodeJS (Express) - project structure and mongo connection

I started a new project from scratch with ExpressJS.
Everything works fine but now I begin to have a dozen of 'app.get(....)' function and I need to give the project a structure.
What I have in mind is quite simple, it should have a folder named 'routes' containing a file such as 'module1.js', with all of the app.get related to that module. (like I've seen in many examples)
The issue is how to tell Express to route 'http://url/module1/' to that route file and how to pass it a param variable, containing for instance the mongodb connection.
what I tried is :
var params = {
db: myMongoConnection
};
var mod1 = require('routes/module1');
app.use('/module1', mod1);
but now I still miss the 'params'.
If I try to pass it as an argument to the require method i get an error saying it needs middleware.
Another issue is related to the fact that the myMongoConnection is valid in the connection callback, so I think i need to require and use the route.js inside the MongoClient connect callback.
Any idea?
thanks a lot
For custom modules, create a folder, call it modules
In its index.js, expose the modules that you need.
Something like,
var mods = [
'mod1',
'mod2',
];
function init() {
var expose = {};
var params = {
db: myMongoConnection
};
mods.forEach(mods, function (mod) {
expose[mod] = require('./' + mod)(params);
});
return expose;
}
// export init
module.exports = init;
In mod1.js, wrap the params
module.exports = function(params) {
// all your functions here will have access to params.
}
Then in, server/app.js, require this and set it in the app.
app.set('mods', require('path-to/modules'));
Now, you can access all your modules, using app.get('mods').moduleName.methodname

Where do I put database connection information in a Node.js app?

Node.js is my first backend language and I am at the point where I am asking myself "where do I put the database connection information?".
There is a lot of good information regarding this issue. Unfortunately for me all the examples are in PHP. I get the ideas but I am not confident enough to replicate it in Node.js.
In PHP you would put the information in a config file outside the web root, and include it when you need database data.
How would you do this in Node.js? using the Express.js framework.
So far I have this:
var express = require('express'), app = express();
var mysql = require('mysql');
app.get('/', function(req,res) {
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'store'
});
var query = connection.query('SELECT * from customers where email = "deelo42#gmail.com"');
query.on('error', function(err) {
throw err;
});
query.on('fields', function(fields) {
console.log('this is fields');
});
query.on('result', function(row) {
var first = row.first_name;
var last = row.last_name;
res.render('index.jade', {
title: "My first name is " + first,
category: "My last name is " + last
});
});
});
app.listen(80, function() {
console.log('we are logged in');
});
As you can see I have a basic express application with 1 GET route. This route sets off the function to go to the database and pull out information based on an email address.
At the top of the GET route is the database connection information. Where do I put that? How do I call it? How do I keep it out of web root, and include it like PHP ? Can you please show me in a working example. Thanks!
I use the Express Middleware concept for same and that gives me nice flexibility to manage files.
I am writing a detailed answer, which includes how i am use the config params in app.js to connect to DB.
So my app structure looks something this:
How i connect to DB? (I am using MongoDB, mongoose is ORM, npm install mongoose)
var config = require('./config/config');
var mongoose = require("mongoose");
var connect = function(){
var options = {
server: {
socketOptions:{
keepAlive : 1
}
}
};
mongoose.connect(config.db,options);
};
connect();
under the config folder i also have 'env' folder, which stores the environment related configurations in separate files such as development.js, test.js, production.js
Now as the name suggests, development.js stores the configuration params related to my development environment and same applies to the case of test and production. Now if you wish you can have some more configuration setting such as 'staging' etc.
project-name/config/config.js
var path = require("path");
var extend = require("util")._extend;
var development = require("./env/development");
var test = require("./env/test");
var production = require("./env/production");
var defaults = {
root: path.normalize(__dirname + '/..')
};
module.exports = {
development: extend(development,defaults),
test: extend(test,defaults),
production: extend(production,defaults)
}[process.env.NODE_ENV || "development"]
project-name/config/env/test.js
module.exports = {
db: 'mongodb://localhost/mongoExpress_test'
};
Now you can make it even more descriptive by breaking the URL's into, username, password, port, database, hostname.
For For more details have a look at my repo, where you can find this implementation, in fact now in all of my projects i use the same configuration.
If you are more interested then have a look at Mean.js and Mean.io, they have some better ways to manage all such things. If you are beginner i would recommend to keep it simple and get things going, once you are comfortable, you can perform magic on your own. Cheers
I recommend the 12-factor app style http://12factor.net which keeps all of this in env vars. You never should have this kind of information hard-coded or in the app source-code / repo, so you can reuse it in different environments or even share it publicly without breaking security.
However, since there are lots of environment vars, I tend to keep them together in a single env.js like the previous responder wrote - although it is not in the source code repo - and then source it with https://www.npmjs.org/package/dotenv
An alternative is to do it manually and keep it in, e.g. ./env/dev.json and just require() the file.
Any of these works, the important point is to keep all configuration information separate from code.
I agree with the commenter, put it in a config file. There is no ultimate way, but nconf is also one of my favourites.
The important best practise is that you keep the config separate if you have a semi-public project, so your config file will not overwrite other developers.
config-sample.json (has to be renamed and is tracked with for example git)
config.json (not tracked / ignored by git)

How do I overload the functionality of app.listen in expressjs

I've been trying to create (basically) a factory function that configures and builds an expressjs server for a dozen smaller specialized servers I have. For part of this I want to augment the listen function.
I would like to know the best way to go about this. I'm also looking for a reusable design choice here.
Server is created normally:
var httpServer = express();
...
Because of the way express is designed (Not sure if I am correct) I cannot access a {whatever}.prototype.listen. So I have come up with two approaches.
Using an additional variable in the current scope:
var oldListen = httpServer.listen;
httpServer.listen = function(callback){
...
oldListen.call(httpServer, options.port, options.host, function(){
...
if ( typeof callback == 'function' ) callback();
});
};
Which works and is fairly straight forward but then I have a variable hoisting wart. I also have a closure solution, but I think it may be too obtuse to be practical:
httpServer.listen = (function(superListen){
return function(callback){
...
superListen.call(httpServer, options.port, options.host, function(){
...
if ( typeof callback == 'function' ) callback();
});
};
})(httpServer.listen);
Both examples are part of the factory context and I am intentionally reducing the arguments passed to the function.
Any help would be appreciated.
If you insist on "overloading", make sure you implement the original footprint (such is the nature of overloading). Express listen is just an alias to node's internal http listen method:
server.listen(port, [host], [backlog], [callback]);
UPDATE: Express even suggests using node's server API for custom implementations: http://expressjs.com/4x/api.html#app.listen
Otherwise, you should create your own custom listen method which would be defined like:
httpServer.myCustomListen = function (callback) {
httpServer.listen.call(httpServer, options.port, options.host, callback);
}
The second option is your best bet, but in order for it to work, you must extend the express library. Express is open source and hosted on Github. Fork it and modify it as you please. Periodically pull in new updates so you stay up-to-date with the core library. I do this all the time with node modules.
There are two benefits from doing it this way:
You have complete control to customize the code however you see fit while staying up to date with the code written by the original authors.
If you find a bug or build a cool feature, you can submit a pull request to benefit the community at large.
You would first fork the repository, then grab the URL for your fork, clone it, and then add a reference to the original "upstream" repo:
git clone [url_to your_fork]
cd express
git remote add upstream git#github.com:strongloop/express.git
Then you can push changes to your own repo (git push). If you want to get updates from the original repo, you can pull from the upstream repo: git pull upstream master.
If you want to add your custom fork of express as an npm module for a project, you would use the following:
npm install git://github.com/[your_user_name]/express.git --save
As Victor's answer pointed out, express's prototype is in express/lib/application.js. That file is used to build express and is exported via the application namespace in express/lib/express.js. Therefore, the .listen function can be referenced using express.appliction.listen.
One can use this method then: (similar to Victor's method)
var express = require('express');
express.application._listen = express.application.listen;
express.application.listen = function(callback) {
return this._listen(options.port, options.host, callback);
};
One can also use Lo-dash's _.wrap function if you don't want to store the base function in a variable yourself. It would look something like this:
var express = require('express');
var _ = require('lodash');
express.application.listen = _.wrap(express.application.listen, function(listenFn) {
return listenFn(options.port, options.host, callback); // Called with the same this
};
However, using these methods would run into the problems that you mentioned in your question (variable hoisting, creating an extra variable). To solve this, I would usually create my own subclass of express.application and replace the .listen function in that subclass and tell express to use that subclass instead. Due to express's current structure, however, you cannot replace express.application with your own subclass without overriding the express() function itself.
Hence, what I would do is to take over express.application.listen completely since it is only 2 lines. It is rather simple!
var express = require('express');
var http = require('http');
express.application.listen = function(callback) {
return http.createServer(this).listen(options.port, options.host, callback);
};
You can even make an https option!
var express = require('express');
var http = require('http');
var https = require('https');
express.application.listen = function(callback) {
return (options.https ? http.createServer(this) : https.createServer({ ... }, this))
.listen(options.port, options.host, callback);
};
Note: One of the other answers mentions forking express and modifying it. I would have a tough time justifying that for such a small function.
You should be able to easily overload the express listen function. You can access it in the following Object path: express.application.listen
So, you can implement something like this:
var express = require('express');
express.application.baseListen = express.application.listen;
express.application.listen = function(port) {
console.log('Port is: ' + port);
this.baseListen(port);
};
The implementation of the listen function is in the following path under the express module folder: node_modules\express\lib\application.js
Bind and listen for connections on the given host and port. This method is identical to node's http.Server#listen().
var express = require('express');
var app = express();
app.listen(3000);
The app returned by express() is in fact a JavaScript Function, designed to be passed to node's HTTP servers as a callback to handle requests. This allows you to provide both HTTP and HTTPS versions of your app with the same codebase easily, as the app does not inherit from these (it is simply a callback):
var express = require('express');
var https = require('https');
var http = require('http');
var app = express();
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
The app.listen() method is a convenience method for the following (if you wish to use HTTPS or provide both, use the technique above):
app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
Reference:http://expressjs.com/api.html
Hope This helps.

Node.js - socket.io web app

I've created a basic node.js server program and used socket.io to pass some field data from a client (see below). Pretty chuffed as I'm new to this business. I liked this node-express-socket.io approach as its all Javascript and is apparently usable by most browsers (incl' mobile). The problem is I've kind of fumbled my way through and do not not fully understand what I have created! Two questions...
1) Do I need to use the "//ajax.googleapis.com...jquery..."? This is annoying as the browser will need to have an internet connection to work. Is there another way to access the html doc elements without needing an internet connection?
2) What does the "app.use(express.static...." line do? The "app.get..." function seems to require this to work.
If there are any other general comments about my code please let me have it!
Cheers,
Kirbs
Client side code:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect(document.location.protocol+'//'+document.location.host);
function clicked(){
$(function(){
var makeInput=$('.app').find('#make').val();
var modelInput=$('.app').find('#model').val();
socket.emit('make', makeInput);
socket.emit('model', modelInput);
});
};
</script>
Server side code:
var express = require('express');
var http = require('http');
var socketio = require('socket.io');
var app = express();
var server = http.createServer(app);
var io = socketio.listen(server);
app.use(express.static(__dirname));
app.get('/', function (req, res) {
res.render(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.on('make', function (make) {
socket.on('model',function (model){
console.log('recieved message:', make+','+model);
});
});
});
server.listen(8000);
1) As you have setup a static web server (see answer 2), you could simply download the jquery source and serve the .js file from there.
2) "app.use(express.static...." configure a static webserver and setting up the http root directory to the directory that your node.js script lives, as indicated by the __dirname variable. For more detail, see app.use API reference.
As result, I would recommend you change you app.use to:
app.use(express.static(__dirname + '/public'));
and place all your static files, including your jquery file(s), under a public subdirectory.
Also, your server side code has a dependency on sequence of make and model which should be changed. For example, if you switch the emit order to model then make, you should see that your server's console.log will be picking up the make from the previous call.
Instead, try something like:
// On server:
socket.on('info', function (info) {
console.log('recieved message:', info.make+','+info.model);
});
// On client:
socket.emit('info', { make: makeInput, model: modelInput })
1) You can serve the jQuery library also from your server if you like that better. You should put it in the public/vendor or public/js folder in your project.
2) This is a middleware call from Express framework, which uses in turn the Connect middleware stack. Read up on this here.

Resources