How to use MVC and include files in my node app - javascript

I Have a Node app, I have three files and am trying to structure my node in a MVC pattern.
I want a way to put all my requires and variables in my server.js all the routes in my routes.js and my functions in my controller.js.
My router is fine and works.
How do I include the functions from controller in my server file
I have:
server.js
var configure = require('./router');
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
// get an instance of router
var router = express.Router();
configure(router);
var request = require('request');
var nodePardot = require('node-pardot');
var bodyParser = require('body-parser');
var rp = require('request-promise');
// Start the server
app.listen(port);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({extended: true})); // support encoded bodies
console.log('Test server started! At http://localhost:' + port); // Confirms server start
//
// // START THE SERVER
// // ==============================================
app.listen(port);
console.log('Server has started!! ' + port);
// apply the routes to our application
app.use('/', router);
router.js`
module.exports = function (router) {
// route middleware that will happen on every request
router.use(function (req, res, next) {
// log each request to the console
console.log(req.method, req.url);
// continue doing what we were doing and go to the route
next();
});
// home page route (http://localhost:8080)
router.get('/', function (req, res) {
res.send('im the home page!');
});
router.get('/login', function (req, res) {
res.send('this is the login form');
})
// process the form (POST http://localhost:8080/login)
.post('/login', function (req, res) {
console.log('processing'); // shows on console when post is made
res.send('processing the login form!'); // output on postman
});
};
controller.js
var password = 'gf.09';
var userkey = 'dfgg';
var emailAdmin = 'rt.r#rt.co.uk';
// Start the server
app.listen(port);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({extended: true})); // support encoded bodies
console.log('Test server started! At http://localhost:' + port); // Confirms server start
var firstFunction = function () {
return new Promise (function (resolve) {
setTimeout(function () {
app.post('/back-end/test', function (req, res) {
console.log(req.body);
var login = req.body.LoginEmail;
res.send(login);
resolve({
data_login_email: login
});
});
console.error("First done");
}, 2000);
});
};
var secondFunction = function () {
return new Promise (function (resolve) {
setTimeout(function () {
nodePardot.PardotAPI({
userKey: userkey,
email: emailAdmin,
password: password,
DEBUG: false
}, function (err, client) {
if (err) {
// Authentication failed
console.error("Authentication Failed", err);
} else {
// Authentication successful
var api_key = client.apiKey;
console.log("Authentication successful !", api_key);
resolve({data_api: api_key});
}
});
console.error("Second done");
}, 2000);
});
};
function thirdFunction(result) {
return new Promise (function () {
setTimeout(function () {
var headers = {
'User-Agent': 'Super Agent/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded'
};
// Configure the request
var api = result[1].data_api;
var login_email = result[0].data_login_email;
var options = {
url: 'https://pi.pardot.com/api/prospect/version/4/do/read',
method: 'POST',
headers: headers,
form: {
'email': login_email,
'user_key': userkey,
'api_key': api
},
json: true // Automatically stringifies the body to JSON
};
// Start the request
rp(options)
.then(function (parsedBody) {
console.error(login_email, "Is a user, login pass!");
})
.catch(function (err) {
console.error("fail no such user");
// res.status(400).send()
});
console.error("Third done");
}, 3000);
}
);
}
// sequence of functions
Promise.all([firstFunction(), secondFunction()])
.then(thirdFunction);
What I have tried
var routers = require('./router');
var controller = require('./test');
// var controller = require('./test.js','./router' );
var express = require('express');
var request = require('request');
var nodePardot = require('node-pardot');
var bodyParser = require('body-parser');
var rp = require('request-promise');
var app = express();
var port = process.env.PORT || 8080;
var router = express.Router();
routers(router);
controller(Promise);
and
module.exports = function (Promise) {
all functions
}
Problem is some of the variables are not available to controller.js so i get errors such as :
app.post('/back-end/controller', function (req, res) {
^

This is dead simple use same logic as you applied in your router.js.
Use something like below in controller.js:
exports.function_name = function(params, ...){
. . .
}
Then access these function by importing the controller.js
var controller = require('./controller.js');
controller.function_name(param..) # execute with required params and callback
If you want to return an object then you can do module.exports
module.exports = Promise.all([firstFunction(), secondFunction()]) .then(thirdFunction);
The controller object contain a promise now so
var controller = require('./controller.js');
controller object directly can be used as a promise no need to call a function now.
A better alternative is to export all the functions from controller.js and then in app.js you can use them with promise.
Promise.all([controller.firstFunction(), controller.secondFunction()]) .then(controller.thirdFunction);

Related

Express.js, get call is returning a 500 error

I created a GET API call intended to fetch every user in my Logins database. For some reason, I keep on getting 500 calls on it. Here is my code:
const http = axios.create({
baseURL: "http://localhost:8080/api",
headers: {
"Content-type": "application/json"
}
});
function fetchUsers(){
http.get("/getusers").catch(err => {
console.log("OOF: " + err.message);
});
}
fetchUsers();
This is the routes file:
const users = require("../controller/users.controller.js");
var express = require('express');
var router = express.Router();
const pathStart = "/api";
// Retrieve all Users
router.get(pathStart + "/getusers", users.findAll);
My routes file is being used in my app.js file:
var indexRouter = require('./routes');
var userRouter = require('./routes/users.routes.js');
var app = express();
app.use('/', indexRouter);
app.use('/', userRouter);
users.controller.js:
// Retrieve all users from the database.
exports.findAll = (req, res) => {
console.log("extracting users");
const user = req.query.user;
var condition = user ? { user: { [Op.like]: `%${user}%` } } : null;
Users.findAll({ where: condition })
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message: err.message || "Error occurred when retrieving users"
})
});
};
This is my output: OOF: Request failed with status code 500
It is because of these two lines:
app.use('/', indexRouter);
app.use('/', userRouter);
Basically you will never enter inside userRouter, as indexRouter catches every request. You need to have something like this below.
In app.js:
app.use('/api/', userRouter);
app.use('/', indexRouter);
In userRouter.js:
const users = require("../controller/users.controller.js");
var express = require('express');
var router = express.Router();
// const pathStart = "/api"; not needed anymore
// Retrieve all Users
router.get("/getusers", users.findAll);
Your fetch logic:
const http = axios.create({
baseURL: "http://localhost:8080/api",
headers: {
"Content-type": "application/json"
}
});
function fetchUsers(){
http.get("/getusers").catch(err => {
console.log("OOF: " + err.message);
});
}
fetchUsers();

How to get full url and send to other js page using node express js

I am trying to access token variable in another page(api.js), how can I use?
index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
var token = req.url;
});
module.exports = router;
module.exports.token1 = token;
api.js [ I want to use token variable in api.js, like this sessionId: requestd.token1 ]
var apiai = require('apiai');
var requestd = require('./index');
var app = apiai('-my-api-key');
var getRes = function(query) {
var request = app.textRequest(query, {
sessionId: requestd.token1
});
const responseFromAPI = new Promise(
function (resolve, reject) {
request.on('error', function(error) {
reject(error);
});
request.on('response', function(response) {
resolve(response);
});
});
request.end();
return responseFromAPI;
};
module.exports = {getRes}
Try
index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
require('./api').get(req ,res) // Be sure your path is correct
});
module.exports = router;
api.js
var api = {
get: function(req, res){
var token = req.url;
console.log(toaken);
}
}
module.exports = api
please update require file statement var requestd = require('./index.js');
and also define "token" variable before this statement module.exports.token1 = token;

Request is not finished yet error with mongoDB and Express

I get a message Request is not finished yet and no data will be sent, if I do patch and delete requests in my app ( the post and get request work well)
Here are my requests
In service (front, Angular 4) I create the requests
api = 'http://localhost:3000/tasks';
deleteData(id) {
return this.http.delete( this.api, id);
}
patch(data) {
return this.http.patch( this.api, data);
}
And then call them in component
this.deleteData(this.checkedItems);
this.service.patch(result.data).subscribe(d => {
this.tasks = d;
});
The service
The PATCH request get req.body via console.log - so it should works, but it doesn't
The DELETE request doesn't get any data! The req.body is empty! But I need to pass the array of ids, so I can't do it via params.
Could you please help me or give a hint? Here is my service
const express = require('express');
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
var Schema = mongoose.Schema;
const app = express();
//Middleware for CORS
app.use(cors());
app.use(express.json());
// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist')));
var todoSchema = new Schema({
taskName: String,
createdAt: Date,
isDone: Boolean,
prioraty: String
}, {
collection: 'tasks'
});
var Model = mongoose.model('Model', todoSchema);
//replace when DB is online
mongoose.connect('mongodb://localhost:27017/admin').then(() => {
console.log("connected");
}).catch (() => {
console.log("not connected");
});
mongoose.connection.once('open', function () {
console.log('mongodb connected.');
});
app.patch('/tasks', function (req, res) {
console.log(req.body);
var updateObject = {
'taskName': req.body.taskName,
'isDone': req.body.isDone,
'prioraty': req.body.prioraty
}
var id = req.body._id;
Model.collection.update({_id : id}, {$set: updateObject});
});
app.delete('/tasks', function(req,res){
console.log('Delete', req.body);
var ids = [];
for (let i = 0; i < req.body.length; i ++) {
ids.push(req.body[i]._id);
}
var myquery = { _id: { $in: ids } };
Model.collection.deleteMany(myquery, function(err, obj) {
if (err) throw err;
});
});
const port = process.env.PORT || '3000';
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port, () => console.log(`API running on localhost:${port}`));
You need to close the connection when you're done handling the request, otherwise the client will wait for the server to send a response until the request timeout is reached.
app.patch('/tasks', function (req, res) {
...
Model.collection.update({_id : id}, {$set: updateObject}, function (err) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
res.sendStatus(200);
});
});
app.delete('/tasks', function(req,res){
...
Model.collection.deleteMany(myquery, function(err) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
res.sendStatus(200);
});
});
As for the DELETE request not having a req.body, that's because Angular 4's http client doesn't allow a body for DELETE requests. Its API for DELETE requests looks like this: this.http.delete(url, httpOptions), with no body support. You'll have to use query parameters if you need to send an array of ids. Query params does support arrays, they look something like this: https://myurl.xyz/tasks?ids[]=1&ids[]=2&ids[]=3
See https://angular.io/guide/http#url-parameters

Pass Soket.io to Express routes

I would use socket.io in my routes file.
I have found multiple methods but no one worked for me.
Now I'm trying this solution
var http = require("http");
var admin = require('firebase-admin');
var firebase = require("firebase");
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var port = process.env.app_port || 8080; // set our port
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var server = app.listen(port);
var io = require("socket.io")(server);
var routerProj = require("./routes/routes")(io);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,*");
next();
});
var config = {
XXX
};
firebase.initializeApp(config);
var serviceAccount = require("./ServiceAcountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://datatable-18f93.firebaseio.com"
});
app.use("/v1", routerProj);
//Create HTTP server and listen on port 8000 for requests
// Print URL for accessing server
console.log("Server running at http://127.0.0.1:8080/");
io.sockets.on("connection", function (socket) {
console.log("a user is connected");
});
Routes.js
var express = require("express"); // call express
var router = express.Router(); // get an instance of the express Router
var admin = require("firebase-admin");
module.exports = function (io) {
/*router.use(function (req, res, next) {
// do logging
io.on('connection', function (socket) {
console.log('User has connected to Index');
});
});*/
router.use(function (req, res, next) {
io.on('save-message', function (socket) {
console.log('User has connected to Index');
});
});
router
.route("/")
.get(function (req, res, err) {
// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("/");
// Attach an asynchronous callback to read the data at our posts reference
ref.once("value", function (snapshot) {
var list = [];
snapshot.forEach(function (elem) {
list.push(elem.val());
})
list = JSON.stringify(list);
//list = JSON.parse(list)
//console.log(JSON.stringify(list))
res.send(list);
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
res.status(500).send(errorObject.code);
});
});
router
.route("/")
.post(function (req, res, err) {
console.log(req.body);
// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("/");
// Attach an asynchronous callback to read the data at our posts reference
ref.push(
{
"text": req.body.text
}
);
});
return router
}
sockets are working in my server.js file , in console I get the message :"a user is connected" when I run my angular app.
But in my browser I run http://127.0.0.1:8080/v1in router.js console.log is not working, so sockets is not getting passed.
I have tried to emit an event :
ngOnInit() {
this.socket.emit('save-message', { room: "hello" });
}
In my router.js :
router.use(function (req, res, next) {
io.on('save-message', function (socket) {
console.log('User has connected to Index');
});
});
console.log don't print anything.

How to correctly call fs.writeFile

I can't figure out how to write on a JSON file.
I'm working on a Single Application Page, using mostly AngularJS and Node.js
This is my code:
--index.html--
<script type="text/ng-template" id="pages/Animazione.html">
...
<td><input id="clickMe" type="button" value="clickme" ng-click="doPost()" /></td>
--app.js--
var App = angular.module('myMovie', ['ngRoute']);
...
.when('/Animazione', {
templateUrl : 'pages/Animazione.html',
controller : 'AnimazioneController'}
)
...
App.controller('AnimazioneController', ['$scope','$http', function($scope, $http) {
$http.get('Animazione.json').success(function(response)
{
$scope.myData=response;
})
.error(function()
{
alert("Si รจ verificato un errore!");
});
$scope.doPost = function()
{
writeOutputFile({test: 1});
};
}]);
--index.js-- (Server)
function writeOutputFile(data, success, fail) {
var fs = require('fs');
fs.writeFile('auth.json', JSON.stringify(data), function(error) {
if(error) {
console.log('[write output]: ' + err);
if (fail)
fail(error);
} else {
console.log('[write output]: success');
if (success)
success();
}
});
}
Is there any call or any function that I'm doing wrong?
As far as I know, you can't call a function directly which in the server via client.
To do this, define and end point in the server and from client make a call to that end point. Inside the handler for that end point in server call your function to write to file.
Eg: In server define /writefile endpoint like below (where express is used in server side) Add below contents to index.js
var express = require('express');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var fs = require('fs');
var http = require('http');
var cors = require('cors');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(cors());
app.post('/writefile', function(req, res) {
var fileData = req.body.fileContent;
fs.writeFile('message.txt', fileData , function(err) {
if (err) {
res.status(500).jsonp({ error: 'Failed to write file' });
}
res.send("File write success");
});
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
var port = 3000;
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
Now your server is running in 3000 port.
In client:
$http({
method: 'POST',
url: 'http://localhost:3000/writefile', // Assuming your running your node server in local
data: { "fileContent": {"test": 1} } // Content which needs to be written to the file 'message.txt'
}).then(function(){
// Success
},
function(error) {
//error handler
console.error("Error occured::",error);
});

Categories