how to access app outside the server.js file? - javascript

I have two files:
server.js
const app = express();
require('./server/config/crawlerBasedModels.config').basedModels()
.then((models) => {
app.locals.basedModels = models;
console.log(app.locals.basedModels);
})
.catch(err => console.log(err));
crawlerBasedModels.config:
const fs = require('fs');
const Promise = require('bluebird');
module.exports = {
basedModels: () => {
return new Promise((res, rej) => {
let basedModelsPath = require('../config/exportFolderPath');
const basedModels = JSON.parse(fs.readFileSync(basedModelsPath + '/basedModels.json'));
if(basedModels) {console.log(basedModels); return res(basedModels);}
return rej('couldnt load basedModels file!');
});
}
};
in console i see:
undefined
My question is how can I set a global var within my app that will be exposed for the entire of the app lifetime?

There are two ways to accomplish this.
<app.js>
const app = module.exports = express();
app.locals.test = 'test is valid';
<anotherfile.js>
const app = require('./app');
console.log(app.locals.test);
Now, anytime you require app, it will set the app.locals and it'll be accessible to you in another file.
Another way to do it is to have a separate blank file, called global.js.
<global.js>
empty file
<test1.js>
const global = require('./global');
global.test = 'setting var in test1.js';
<test2.js>
const global = require('./global');
console.log('global vars %j', global);
<node.js runtime>
> const a = require('./test1.js')
> const b = require('./test2.js');
global vars {"test":"setting var in test1.js"}
The only caveat here will be test1 has to be required before you can access the global variable. But, your use case demands that as well, setting something in app.locals and then using it somewhere else.

Related

Node.js - accessing a const from a function within http.get

In the code below I am accessing the current bitcoin value in GBP. The console.log works fine.
value.js
http = require('http');
http.get({
host: 'api.coindesk.com',
path: '/v1/bpi/currentprice.json'
},
function get_value(response) {
// Continuously update stream with data
var body = '';
response.on('data', function(d) { body += d; });
response.on('end', function() {
// Data reception is done, do whatever with it!
var parsed = JSON.parse(body);
var final_value = parsed.bpi.GBP.rate
console.log(final_value)
module.exports = final_value;
});
}
);
However when I try to access this value (final_value) from another file:
server.js
PORT = 4000;
var http = require('http');
const value = require('./value.js');
var server = http.createServer((req, res) => {
res.write("Create server working");
});
server.listen(PORT, () => {
console.log(value);
});
All I get back is {}.
I'm quite new to node.js and more used to python. I've looked into accessing values from functions within functions but couldn't find any kind of solution.
Does anyone have a recommendation as to how I could access the variable final_value from a separate file?
I honestly prefer to use express than native Node, but given that you are using it, I can give you some tips to help you with it:
If you want to use a js file from other, you should export what you want to share between them. In the example that you are showing it should be something like this (note that I'm exporting the function and also using it as a Promise in a function):
const http = require('http');
module.export = function () {
return new Promise(function (resolve) {
http.get({
host: 'api.coindesk.com',
path: '/v1/bpi/currentprice.json'
},
function get_value(response) {
// Continuously update stream with data
var body = '';
response.on('data', function(d) { body += d; });
response.on('end', function() {
// Data reception is done, do whatever with it!
var parsed = JSON.parse(body);
var final_value = parsed.bpi.GBP.rate
console.log(final_value)
resolve(final_value);
});
}
);
});
}
then you can use it in your server file in this way:
...
server.listen(PORT, () => {
value.then(result => console.log(result));
});
You can change module.exports = final_value to exports.final_value = final_value, and then retrieve the value with
const { final_value } = require('./value.js');
...
server.listen(PORT, () => {
console.log(final_value);
});
The advantage of this is that you can now export other values from the value.js file, and just require them in the same way. The main difference between module.exports and exports.value is that module.exports is an object that has exports as a property, and exports is just an alias for module.exports. Essentially, by using the module.exports syntax, you are assigning module.exports the value of the object you are assigning to it.

Cost of importing in Javascript [duplicate]

So I'm planning to separate my functions into separate files and then import them into a single index.js which then becomes the main exporter. So I'm wondering if having something like var bcrypt = require('bcrypt') in several of my files be slower than just having it in one file.
Here's how I'm planning to group and export in index.js
const fs = require('fs');
const path = require('path')
const modules = {}
const files = fs.readdirSync(__dirname)
files.forEach(file => {
if (file === 'index.js') return
let temp = require(path.join(__dirname, file))
for (let key in temp) {
modules[key] = temp[key]
}
});
module.exports = modules
As an example of what I mean:
file1.js
var bcrypt = require("bcrypt");
module.exports.file1test = "hi"
file2.js
var bcrypt = require("bcrypt");
module.exports.file2test = "bye"
No, it does not. Whenever a module is required for the first time, the module's code runs, assigns something to its exports, and those exports are returned. Further requires of that module simply reference those exports again. The logic is similar to this:
const importModule = (() => {
const exports = {};
return (name) => {
if (!exports[name]) exports[name] = runModule(name);
return exports[name];
};
})();
So, multiple imports of the same module is no more expensive than referencing an object multiple times.

More than one connection opened in MongoDB using NodeJS and Mongoose

I am new to Node and MongoDB, so please forgive me if I sound too naive.
I have a DB class that creates a connection to MongoDB
db.service.js
const mongoose = require("mongoose");
const fs = require("fs");
const dbConfigs = JSON.parse(fs.readFileSync("/configs.json"));
const dbHost = dbConfigs.DB_HOST;
const dbName = dbConfigs.DB_NAME;
const dbPort = dbConfigs.DB_PORT;
const dbUrl = "mongodb://" + dbHost + ":" + dbPort + "/" + dbName;
const dbOptions = {
useNewUrlParser: true
};
let dbConnection = mongoose.createConnection(dbUrl, dbOptions);
exports.getConnection = () => {
if (dbConnection)
return dbConnection;
}
exports.closeConnection = () => {
if (dbConnection)
return dbConnection.close();
}
Next I have another module that creates a Schema for MongoDB
schema.js
const connection = require("./db.service").getConnection();
const Schema = require("mongoose").Schema;
const SampleSchema = new Schema({...})
exports.Sample = connection.model("Sample", SampleSchema);
Then I have another module that makes use of this Schema to save objects
logger.js
const Sample = require("./schema").Sample;
exports.log = () => {
let body = {....};
let sampleObj = new Sample(body);
return sampleObj.save(sampleObj);
The Main module
Main.js
const logger = require("./logger");
for (let i=0; i < 100; i++) {
logger.log();
}
When I run node Main.js, everything is saved, but when I check the MongoDB with the command db.serverStatus.connections, I see 6 connections open.
I don't know how it's getting there. I know the command mongo itself keep a connection open, but where are the other 5 connections coming from?
I have checked this, which seems to suggest that Mongoose opens 5 connections for an application, but my application is firing just one transaction, where is the need to open 5 connection then? Couldn't it be done with just one?
Mongoose is managing the connections itself; it tries to optimize the speed of the request.
You are seeing it like you are using only one transaction, but behind the scene mongoose is probably doing much more than you expect.
You can modify the number of connection mongoose can open using the parameter poolSize.
Example :
const dbOptions = {
useNewUrlParser: true,
poolSize: 1,
};
Try it with poolSize equals to 1 and see how much time it takes to execute your transaction, you'll have your answer.

Why is a variable assigned 'this' in module.export function in javascript

I am trying to understand the following code taken from a service created in a feathersjs app.
// Initializes the `users` service on path `/users`
const createService = require('feathers-knex');
const createModel = require('../../models/users.model');
const hooks = require('./users.hooks');
const filters = require('./users.filters');
module.exports = function () {
const app = this;
const Model = createModel(app);
const paginate = app.get('paginate');
const options = {
name: 'users',
Model,
paginate
};
// Initialize our service with any options it requires
app.use('/users', createService(options));
// Get our initialized service so that we can register hooks and filters
const service = app.service('users');
service.hooks(hooks);
if (service.filter) {
service.filter(filters);
}
};
This file is then imported as follows:
// many requires..
const feathers = require('feathers');
// more requires
const services = require('./services');
// other requires
const app = feathers();
Can someone explain as to what does the line
const app = this
do in the code that is creating the service?
It assigns the value of this to a variable (well, a constant) with a name that more clearly describes the value than this does. It is designed to make the code easier for maintainers to understand.

Unable to export variables within function expressjs/requestjs

My export code
//export.js
var express = require('express'),
fs = require('fs'),
request = require('request'),
cheerio = require('cheerio'),
app = express();
var episode = [],
title = [],
synopsis = [],
reviews = [],
date = [];
exports.showGrab = function(url,response){
request(url,response, function(error, response, html){
var $ = cheerio.load(html),
shows = {bitten:['http://www.tv.com/shows/bitten-2013/episodes/']};
$('.no_toggle._clearfix').eq(1).filter(function(){
var data = $(this);
episode = data.children().first().children().last().text();
exports.episode = episode;
})
})
}
console.log(episode); // => defined as [] not the value given in the function
//import.js
var express = require('express'),
fs = require('fs'),
request = require('request'),
cheerio = require('cheerio'),
app = express(),
server = require('./export');
console.log(server.episode);
server.showGrab('http://www.tv.com/shows/bitten-2013/episodes/');
within the import script using the function server.showGrab works fine but I need access to the variables within the show grab function in my import script. I believe this problem boils down to a scope issue, if I export variables outside a function they work fine but I was under the impression that declaring variables the way I have done would make them global. How can I run this function in the import script whilst still passing it a url and getting back episode to work with?
#Pointy you were right the import script was calling the value before it was defined
//import.js
if (server.episode === undefined){
var test = setInterval(function(){
if (server.episode != undefined){
clearInterval(test);
}
console.log(server.episode);
}, 1000);
}
this does the trick, for some reason using else instead of wrapping an if in an if does not work.

Categories