Node.js: Execute server scripts via front-end - javascript

I'd like to execute some specific node JS files with an on-click event at my Website.
I'm using express to run my server and website. I think the right way to do this is using jQuery with some GET requests. The JS files are working, if i call them simply in the console with "node examplefile.js"
The file looks like this:
var MapboxClient = require('mapbox');
var client = new MapboxClient('');
client.listStyles(function (err, styles) {
console.log(styles);
});
I want to execute this file everytime an on-click event occurs.
Do I have to export this as a module to my app.js? This is what I wanted to do, but I failed in the implementation.
Any suggestions or simple examples on how to realize this?

1.Write your examplefile.js within a function
function a(){
var MapboxClient = require('mapbox');
var client = new MapboxClient('');
client.listStyles(function (err, styles) {
console.log(styles);
});
2.Include examplefile.js in your app.js
<script src="examplefile.js" type="text/javascript"></script>
3.Then call a() by onclick() event from your app.js file
<input type="button" onclick="javascript: a();" value="button"/>
That is what i understood, you are trying to do.

It's much better to create a new module and then call it from express app
create new module (getStyles.js):
var MapboxClient = require('mapbox');
var client = new MapboxClient('');
module.exports = function (done) {
client.listStyles(function (err, styles) {
if (err) {
return done(err);
}
done(null, styles);
});
}
Use it inside express app:
...
var getStyles = new MapboxClient('path/to/getStyles');
app.get( '/your/route/here', function (req, res, next) {
getStyles( function (err, styles) {
if (err) return next(err);
res.render('view', styles)
});
});
...
However if you want to execute a command line from express, then use exec function, here is an example:
...
const exec = require('child_process').exec;
app.get( '/on/click/buton/route', function (req, res, next) {
exec('/usr/bin/node file/path/.js', function (err, stdout, stderr) {
if (err) {
return next(err);
}
// send result to the view
res.render('veiw', { res: stdout});
});
});
...

Related

How to modularize an express app - with a function, a class and req.pipe?

Here below there are two servers and two gqlServers. All combinations of them work.
The challenge is to extend express with some additional predefined code patterns shared across several apps, exposed through additional methods.
Which combination of a server and gqlServer is considered best practice and best for performance?
server:
server_A is a function that returns a class
server_B is a function that returns a function
gqlServer:
gqlServer_01 uses req.pipe
gqlServer_02 has the original express() passed into it
function gqlServer_01(options) {
let gqlApp = express();
gqlApp.use(options.route, function(req, res, next) {
res.send('gqlServer 01');
// next();
});
gqlApp.listen(8001, err => {
if (err) throw err;
console.log(`>> GQL Server running on 8001`);
});
}
function gqlServer_02(app, options) {
app.use(options.route, function(req, res, next) {
res.send('gqlServer 02');
// next();
});
}
// THIS SERVER ?
function server_A(config = {}) {
config = deepmerge(def_opt, config);
let app = express();
app.get('/', function(req, res, next) {
res.send('root');
// next();
});
class Server {
constructor(opt) {
this.opt = opt;
}
gql(props = {}) {
// THIS GQL SERVER ?
gqlServer_01({ route: '/gql-01' });
app.use('/gql-01', function(req, res) {
req.pipe(request(`http://localhost:8001/gql-01`)).pipe(res);
});
// OR THIS GQL SERVER ?
gqlServer_02(app, { route: '/gql-02' });
}
}
app.listen(8000, err => {
if (err) throw err;
console.log(`>> Server running on 8000`);
});
return new Server(app, config);
}
// OR THIS SERVER ?
function server_B(config = {}) {
config = deepmerge(def_opt, config);
let app = express();
app.get('/', function(req, res, next) {
res.send('root');
// next();
});
app.gql = function(props = {}) {
// THIS GQL SERVER ?
gqlServer_01({ route: '/gql-01' });
app.use('/gql-01', function(req, res) {
req.pipe(request(`http://localhost:8001/gql-01`)).pipe(res);
});
// OR THIS GQL SERVER ?
gqlServer_02(app, { route: '/gql-02' });
};
app.listen(8000, err => {
if (err) throw err;
console.log(`>> Server running on 8000`);
});
return app;
}
The goal is to have the best solution in order to create an npm package out of this and reuse the methods over several projects easily. The project was highly simplified for the sake of clarity.
I don't think you will have performance issues in any of these examples, so the question remains which of them is more modular.
If you are willing to make an npm package out of these, you shouldn't be calling express() inside your server code. Instead you should be passing the app as a parameter. This will allow you to reuse existing express apps initialized elsewhere. For this reason I would go for gqlServer_02
You also want to create a new server each time you call the module function, so I'd go with server_A for this reason. However it needs to receive the express app as parameter, in order to reuse existing express objects. I would also put the app.listen call inside a function in the Server class.

How to kill a Python-Shell module process in Node.js?

I am currently using the python-shell module in a Node based web interface. The issue I am having is mostly syntactical. The code below shows the generation of a python script.
var PythonShell = require('python-shell');
PythonShell.run('my_script.py' function (err) {
if (err) throw err;
console.log('finished');
}):
This is just an example script from here. How do I relate this to node's
var procc = require('child_process'.spawn('mongod');
procc.kill('SIGINT');
The documentation states that PythonShell instances have the following properties:
childProcess: the process instance created via child_process.spawn
But how do I acutally use this? There seems to be a lack of examples when it comes to this specific module
For example -
var python_process;
router.get('/start_python', function(req, res) {
const {PythonShell} = require("python-shell");
var options = {
pythonPath:'local python path'
}
var pyshell = new PythonShell('general.py');
pyshell.end(function (err) {
if (err) {
console.log(err);
}
});
python_process = pyshell.childProcess;
res.send('Started.');
});
router.get('/stop_python', function(req, res) {
python_process.kill('SIGINT');
res.send('Stopped');
});

Pass data from express route into node module export function

I am new to node, I think I need to use middleware, but I can't warp my head around what it is actually used for, or if this is where it is meant to be used. I have data that is being posted from my view into an express route.
ROUTE - route.js
var GetPlayer = require('./models/getPlayer.js');
module.exports = function(app) {
app.post('/api/getPlayer', function(req, res) {
//GetPlayer.apiGetPlayer(req.body.username);
console.log(req.body.username); //this logs the correct data
});
}
but now I need to pass that data into a node api call and send that response back to the client. But I can not get the route to call that function or pass the data into it.
MODULE.EXPORT - getPlayer.js
module.exports = {
apiGetPlayer: function(error, res) {
console.log("in get player");
console.log(res);
}
}
You would only want to use an Express middleware if this is something you want to do for more than one route (ie. parsing request body's from JSON to actual Object using body-parser). That seems like it could be overkill based on the supplied code. One way to approach this is to just take the username and pass a callback function in to getPlayer. Then when the callback function passed to apiGetPlayer() returns, respond back to the requester based on the result of apiGetPlayer().
getPlayer.js
module.exports =
// callback is an error-first callback function
apiGetPlayer: function(username, callback) {
let err;
let player;
// Logic for getting player go here
// If an error occurs return an error to the callback
if (err)
return callback(err, null);
return callback(null, player);
}
}
/api/getPlayer route
app.post('/api/getPlayer', (req, res) => {
GetPlayer.apiGetPlayer(req.body.username, (err, player) => {
if (err)
return res.status(500).send(err);
return res.status(200).send(player);
});
});

how to run different .js file in one server.js file in NODE JS?

this is demo.js file and i want to use this file in server.js file so that i can use diffrent js files in one server file.
Demo.js:
app.get('/add User', function (req, res) {
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/project';
MongoClient.connect(url, function (err, db) {
var collection = db.collection('users');
collection.find({name: 'shruti'}).toArray(function (err, result) {
console.log(, result);
db.close();
});
Server.js:
var a = require('./demo.js');
vr http=require("http");
var server = http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
response.write(a);
res.end();});
server.listen(7860);
A possible sample would look like :
demo.js
var myModule = {
defineRoutes: function(router){
//do something...
}
}
module.exports = myModule;
server.js
var myModule = require('demo.js');
myModule.defineRoutes(router);
As stated, you need to export.
When you do:
var item = require("mymodule");
Require returns an object, which is a reference the value of module.exports for that given file - in your case demo.js.
You can write your modules a few ways as some people have shown you. Because it is encapsulated you basically are identifying what is public or can be called. Few ways to write it - you could also do:
module.exports = {
yourCall: function () {
console.log("stuff here");
}
};
As stated by #ishann, who is dead on here, you are writing something you assume might be populated. Going to a database and returning is an asynchronous call - so it will take time to go do that and then for the results to be returned.
Based on your structure - ideally what you want to do is assign the route ( "/addUser" ) which will pass in the response object to you:
app.get('/add User', function (req, res) {
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/project';
MongoClient.connect(url, function (err, db) {
var collection = db.collection('users');
collection.find({name: 'shruti'}).toArray(function (err, result) {
console.log(, result);
db.close();
// set the type
res.writeHead(200, {"Content-Type": "application/json"});
res.write(result);
});
Just looks like your code needs a bit of reorg, but separting concerns is good. You might want to also check out Express as a framework for node.

Why is the Formidable `form.parse` callback not running in Express?

I am using the formidable package to handle file uploads on my server.
This is my express.js app code:
var formidable = require("formidable"),
http = require("http"),
util = require("util");
app.post("/admin/uploads", function (req, res) {
console.log(req.files, req.fields); //It prints
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
console.log("Inside form parse."); //its not printing
console.log(err, fields, files); //its not printing
});
form.on("file", function (name, file) {
console.log("file=" + file);
}); //its not printing
form.on("error", function (err) {
console.log(err);
}); //its not printing
form.on("aborted", function () {
console.log("Aborted");
}); //its not printing
console.log(form); //it prints
});
In the above code, the form.parse and form.on callbacks are never run. How can I solve this issue?
I had the same problem when using Next.js API routes with Formidable. Like the other answer points out, you have to remove the body parser. In Next.js, you can export a config object and disable body parsing.
// /pages/api/form.js
import { IncomingForm } from "formidable";
export default function handler(req, res) {
// formidable logic
}
// VV important VV
export const config = {
api: {
bodyParser: false,
},
};
It might be that you need to remove body parser
delete app.use(express.bodyParser());
Call form.parse(...) after all on(...) events.
app.post('/admin/uploads', function(req, res) {
var form = new formidable.IncomingForm();
form.on('file', function(name, file) { });
form.on('error', function(err) { });
form.on('aborted', function() { });
form.parse(req, function(err, fields, files) { });
});
Please add the error handlers and send the error message otherwise it is hard to get an answer.
form.on('error', function(err) { console.log(err); });
form.on('aborted', function() { console.log('Aborted'); });
See the formidable documentation : doc
I forgot to add enctype="multipart/form-data" to my html form, maybe this will help somebody :)
Even if you remove body-parser and use express.json() etc... you will have same error.
The problem is that express.raw() is causing trouble remove it and it works!

Categories