Dependency Injection in ExpressJS - javascript

I'm learning about Dependency Injection and trying to use it in a simple nodejs app. This application has to fetch some data with an external API. Using DI in that case was simple, I just added the dependency as a parameter of the function and it worked like a charm.
async function foo(URL,get_data){
var bar = await get_data(URL);
return bar;
}
When the application is running, get_data would be the function that does the real request and when unit testing my app it would be a dummy function.
How do I apply this same methodology for ExpressJS?
I want it to access the database when is using the application and dummy data when it is testing, but I can't figure out how because I'm not dealing with properties of functions anymore.
In this example:
// index.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 5000;
var db = require('./model/db')
app.get('/users',(req,res) =>{
db.get_users(function(users){
res.send(users);
})
});
app.listen(PORT, () => console.log(`Server listening to port: ${PORT}`));
module.exports = app;
I need to use the real db when the server is running and a mock one when testing with supertest.
// index.text.js
const request = require('supertest');
const app = require('index');
describe("GET /user", function(){
it('should respond with a json', function(done){
request(app)
.get('/users')
.expect('Content-Type',/json/)
.expect(200,done);
});
});

Related

How to correctly call a function from Node.JS to Express.JS

I have a completed script that acts as a parser. The script is written in NodeJS and it works properly. The script returns an array of data and also saves it to my computer.
I would like to run this script from the frontend, at the click of a button. As far as I understand, I have to send a request to the server? It's suggested to use Express for the server, but I still haven't figured out how to call a third-party script from it, much less return any data from it.
Right now all I want is for my script to run when I make a request for the root directory "/" and send me a json in response (or for example a json file)
const express = require('express')
const runParser = require("./parser");
const app = express()
const port = 3000
app.get('/', async (req, res,next) => {
await runParser()
next()
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
All you need for Express is this:
const express = require('express');
const app = express();
const runParser = require("./parser");
const port = 3000;
app.get("/", (req, res) => {
runParser().then(results => {
res.json(results);
}).catch(err => {
console.log(err);
res.status(500).send("error");
});
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
And, then you can access that either by just going to:
http://localhost:3000
from your local host or
http://yourdomain.com:3000
in the browser or by issuing an ajax call to the desired URL from webpage Javascript.
I wouldn't personally put this type of activity on a GET request to / because that can be hit by things like web crawlers, search engines, etc...
It probably belongs on a POST (so crawlers won't issue it) and I'd personally put it on some pathname such as:
app.post("/runparser", (req, res) => {
// put your code here
});
And, then use a form submission or ajax call to that URL to trigger it.

express cant find route

i have a node.js back-end with express sever.
i have routes called templete.rpoutes.js:
const express = require("express");
const templateCtrl = require("../controllers/template.controller");
const router = express.Router();
router.route("/createtemplate").post(templateCtrl.createTemplate);
router.route("/uploadFinalTemplate").post(templateCtrl.uploadFinalTemplate);
// beneath are the routes with issue
router.route("/:templateId/productInfos").get(templateCtrl.productInfos);
router.route("/:templateId").get(templateCtrl.Read);
// router.param("templateId", templateCtrl.templateByID);
module.exports = router;
I have the defined method in template controller where i'm just logging stuff. no backend logic is there yet. so I expect when I make a call to these end point, i should get those logs displayed
I have configured express server as:
app.use("/api/template", templateRoute);
app.use("/api/productInfo", productInfoRoute);
app.use('/api/sendInformation', Notify)
// PORT
const port = process.env.PORT || 5000;
const server = app.listen(port, () => {
console.log("Connected to port " + port);
});
Note: the app is express.router() method and the controllers are required correctly and the other end-points work for the same controller.
so when I send a get request from postman to localhost:5000/api/template/5f870cd3b02fd77d0a576a54 I get a 404 and Not found in my console like this: (Plus the server is running)
as described in the documentation https://expressjs.com/en/guide/routing.html#express-router
const router = express.Router();
router.post("/createtemplate",templateCtrl.createTemplate);
router.post("/uploadFinalTemplate",templateCtrl.uploadFinalTemplate);
router.get("/:templateId/productInfos",templateCtrl.productInfos);
router.get("/:templateId",templateCtrl.Read);

unit test for web socket in node is it possible?

im running unit test using mocha/supertest/chai and I want to test the following code so my question how should I simulate the upgrade event?
const http = require('http');
const app = require('./app');
const server = http.createServer(app);
var webSocket = function (server) {
server.on('upgrade', function (req, socket, head) {
//I want to enter here...

Building an API with node and express, how to get json data from a url?

I’m building an API for a SPA built with Angular 2, for this app I have a stand alone API and than an Angular 2 app. So they are on built on two separate node.js servers. I’m using node.js and express along with 'express-connection' and 'mysql' modules to build a secure API to handle login and registration with JWT’s (json web tokens), along with other tasks of course. So I’ve successfully built this API so I can access data with my Angular 2 app via a URL. I can use the URL ’localhost:3000/data’ to access a json data object from my Angular 2 app running on 'localhost:3001/'. However, I also need the API to have access to this data object (an array of users) once the data becomes available. What is the best way to approach/accomplish this task? The only way I can think of now is to have a setTimeout function that waits for the app to load than uses an http get to grab the data from the url. There must be a cleaner way of accomplishing this task. Heres some code I have working, basically a simple node server running express. I'm somewhat new with building API's and Angular 2 concepts so any help is greatly appreciated.
app.js
/** Dependencies **/
var logger = require('morgan'),
cors = require('cors'),
http = require('http'),
express = require('express'),
errorhandler = require('errorhandler'),
dotenv = require('dotenv'),
bodyParser = require('body-parser');
/** Setup **/
var app = express();
dotenv.load();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
app.use(function(err, req, res, next) {
if (err.name === 'StatusError') {
res.send(err.status, err.message);
} else {
next(err);
}
});
if (process.env.NODE_ENV === 'development') {
app.use(logger('dev'));
app.use(errorhandler())
}
/** Requires **/
require('./config/sql.js')(app);
require('./config/routes.js')(app);
/** Port **/
var port = process.env.PORT || 3001;
http.createServer(app).listen(port, function (err) {
console.log('listening in http://localhost:' + port);
});
routes.js
// routes.js
module.exports = function(app) {
var query = require('./query.js')(app);
app.get('/data', function(req, res) {
query.getData(req,res);
});
};
sql.js
var connection = require('express-myconnection');
var mysql = require('mysql');
module.exports = function(app){
app.use(
connection(mysql,{
host : 'localhost',
user : 'root',
password: ‘password’,
port : 3306,
database: ‘my_project’
}, 'request')
);
};
query.js
// DB Queries
module.exports = function(app){
return {
getData: function(req, res) {
req.getConnection(function(err,connection){
connection.query('SELECT * FROM users',function(err,rows){
// console.log("success: ", rows);
res.json(rows);
});
});
}
}
};
user.js
setTimeout(function(){
// http.get function to call to API and grab data and create variable
},500);
// this is where I need an array of users that I get from a mysql database for login and registration logic
var users = [];
I'm not sure I got why you need the Angular code to talk to a different UrL but I would write the server code to take the requests from Angular and then internally reach out to the other API to get the data required. Basically use the node server to act like a proxy to reach the other API.
jfriend00 is right in his comment, this is a question of asynchronous calls.
You are looking for the initial requests to kick off the following: Frontend Request > NodeJS API > Database Query
And the response to fulfill and return promises to create a response chain in the reverse order: Database Response > NodeJS API > Frontend Response
You are probably looking for the angular function $http.get with .then() to perform your frontend calls. But you also need an asynchronous function to request the data from within the API or a database instance, then provide it on an endpoint that the frontend can consume. For that you need a promise or callback in your server-side code as listed in jfriend00's comment.
Consider working on just your NodeJS API until you can achieve the response and requests you need, and build out your frontend with Angular later. The users.js file is a fine endpoint to start on.

How to properly access the app variable set by express in a node.js app?

I'm building a node.js server and my folder structure looks like this:
server.js
app/routes.js
app/routes/users.js
My problem is that i'm not sure how can i use the app variable inside the users.js file. Do i have to require and setup express again in this file or is there a better/easier way to do it? Here is my sample code(just the bare minimum to understand my problem):
server.js
// Include our packages in our main server file
var express = require('express');
var stormpath = require('express-stormpath');
var app = express();
// Init Stormpath for user management and authentication
app.use(stormpath.init(app));
// Load routes
require('./app/routes')(app);
// Start the server
app.listen(process.env.PORT);
// Stormpath will let you know when it's ready to start authenticating users.
app.on('stormpath.ready', function () {
console.log('Your server is running on port ' + port + '.');
});
app/routes.js
// Import dependencies
const express = require('express');
const stormpath = require('express-stormpath');
// Export the routes for our app to use
module.exports = function(app) {
// Create API group routes
const apiRoutes = express.Router();
// User management: get users, invite users, view user profile
var UsersRoute = require('./routes/users');
apiRoutes.get('/memberinfo', stormpath.loginRequired, UsersRoute.memberInfo);
// Set url for API group routes
app.use('/', apiRoutes);
};
app/routes/users.js
// Protected route test
module.exports.memberInfo = function(req, res){
//how do i access the "app" here?
res.status(200).send({ user: req.user });
}
In your .memberInfo method, you can use req.app to access the app object that is associated with that request.
In cases where you aren't passed a req object that you can use in this way, then you need to initialize the module by calling a method on it and passing it the app object and the module can then store the app object locally so it can use it when desired.

Categories

Resources