refresh page on function call javascript - javascript

I have a script where I am uploading a file to cloudinary, and then when it uploads, call my nodejs function (through js on front-end) and then update the file in my db. its working, but when I call the function, it does not render the page again. Instead nothing happens, but my db updates:
front-end script:
<script src="https://widget.cloudinary.com/v2.0/global/all.js" type="text/javascript"></script>
<script type="text/javascript">
var myWidget = cloudinary.createUploadWidget({
cloudName: 'ps',
uploadPreset: 'ld3l7evv'}, (error, result) => {
if (!error && result && result.event === "success") {
console.log('Done! Here is the image info: ', result.info);
console.log(result.info.secure_url)
var result_url = result.info.secure_url;
console.log("result url is " + result_url)
document.getElementById("url").value = result_url;
var employee_num = document.getElementById('employee_num').value
fetch('/changeProfileImage', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
result_url,
employee_num
})
})
}
}
)
backend (node.js):
app.post('/changeProfileImage', (req, res) => {
var employee_num = req.body.employee_num;
var url = req.body.result_url;
console.log("e " + employee_num)
console.log("u " + url)
var changeProfileImage = "update EMPLOYEES set (PROFILE_IMAGE)= '" + url + "' where EMPLOYEE_NUM = '" + employee_num + "'";
ibmdb.open(ibmdbconnMaster, function (err, conn) {
if (err) return console.log(err);
conn.query(changeProfileImage, function (err, rows) {
if (err) {
console.log(err);
}
console.log("succes")
conn.close(function () {
// console.log("closed the function /index");
});
})
})
})
but it is not actually refreshing / reloading the page after it updates the db. any idea?

Related

using .then nodejs

I have a large function that says, okay add this employee to the db based on what the admin entered. But now I need to check, does this user already exist in the db. so I created a function that does just that called getEmployeeNum, but I need to perform a .then in the main function of /addEmployee to say, see what the result of the function getEmployeeNum is before you perform any of the other requests. see the code below:
app.post('/addEmployee', (req, res) => {
if (req.session.loggedin) {
var firstname = req.body.firstname;
var lastname = req.body.lastname;
var username = req.body.username;
var sales = req.body.sales;
var salary = req.body.salary;
var location = req.body.location;
var role = req.body.role;
var admin = req.body.admin;
var employeenum = req.body.employee_num;
var phonenum = req.body.phone_num;
var org = req.body.org;
var pass = "";
var newPassword = req.body.password
getEmployeeNum(req, res, employeenum)
bcrypt.hash(newPassword, saltRounds, function(err, hash) {
pass = hash
addLogin(req, res, pass, firstname, lastname, username, sales, salary, location, role, admin, employeenum, phonenum)
});
var addEmployee = "insert into EMPLOYEES (FIRSTNAME, LASTNAME, USERNAME, SALES, SALARY, LOCATION, ROLE, ADMIN, EMPLOYEE_NUM, PHONENUM, ORGANIZATION) VALUES ('" +
req.body.firstname +
"', '" +
req.body.lastname +
"', '" +
req.body.username +
"', '" +
req.body.sales +
"', '" +
req.body.salary +
"', '" +
req.body.location +
"', '" +
req.body.role +
"', '" +
req.body.admin +
"', '" +
req.body.employee_num +
"', '" +
phonenum +
"', '" +
org +
"' )";
ibmdb.open(ibmdbconnMaster, function(err, conn) {
if (err) return console.log(err);
conn.query(addEmployee, function(err, rows) {
if (err) {
console.log(err);
}
registerEmail(username, firstname, lastname, req, res)
res.redirect('/employees')
})
})
} else {
res.render('login.ejs')
}
})
function getEmployeeNum(req, res, employeenum) {
var getEmployeeNum = "select * from employees"
ibmdb.open(ibmdbconnMaster, function(err, conn) {
if (err) return console.log(err);
conn.query(getEmployeeNum, function(err, rows) {
if (err) {
console.log(err);
}
for (var i = 0; i < rows.length; i++) {
var employee_num = rows[i]["EMPLOYEE_NUM"]
if (employeenum == employee_num) {
alert("employee already exists")
res.render("addEmployee.ejs")
}
}
conn.close(function() {
// console.log("closed the function /index");
});
});
})
}
is this the right way to do it, or is there a better way? Thanks :)
I see that you're using the callback version of SQL driver. I'll assume that you;re working with mysql2 for simplicity wise.
There is actually a promise version of mysql2 driver
const mysql = require('mysql2/promise');
I'll share with you some of the common patterns I use when working with DB.
// Create a pool for connection
const pool = mysql.createPool({
connectionLimit: process.env.SQL_CON_LIMIT,
host: process.env.SQL_SERVER,
port: process.env.SQL_PORT,
user: process.env.SQL_USERNAME,
password: process.env.SQL_PASSWORD,
database: process.env.SQL_SCHEME,
timezone: process.env.SQL_TIMEZONE,
});
// To use async to test the connection via conn.ping() before launch server
const p1 = (async () => {
const conn = await pool.getConnection();
await conn.ping();
conn.release();
return true;
})();
// test connection for SQL, add other into array as you like
Promise.all([p1])
.then(() => {
app.listen(PORT, () =>
console.info(
`Application started on port http://localhost:${PORT}/ at ${new Date()}`
)
);
})
.catch((err) => {
console.error('Cannot connect: ', err);
});
The code block above is for setting up, and test connection before starting the server. This can avoid the rare case where DB is not initialized before the request came in (As the server can start before connecting to DB)
const makeQuery = (query, pool) => {
return async (args) => {
const conn = await pool.getConnection();
try {
let results = await conn.query(query, args || []);
return results[0]; // Result of query is in index 0
} catch (error) {
console.log(error);
} finally {
conn.release();
}
};
};
// Sample query
const queryCheckLogin =
'SELECT COUNT(*) as "match" FROM user WHERE user_id = ? AND password = ?';
// Make it into function!
const checkLogin = makeQuery(queryCheckLogin, pool);
app.post('/api/login', async (req, res) => {
let { user_id, password } = req.body;
// Obtain sha1 password from submitted password
password = sha1(password);
try {
let results = await checkLogin([user_id, password]);
// Return the credential (supposedly token) when record is matched
if (results[0]['match'] !== 0) {
res.status(200).json({ login: 'success', user_id, password });
} else {
// return 401 if record not found
res.status(401).json({ error: 'No such username or password' });
}
} catch (error) {
console.log(error);
res.status(400).json(error);
}
});
The code block above shows the factory function to deal with the general form of getting the result from a query, so you won't clutter the logic in middleware. So you will write out whatever query you will do, make it into function via makeQuery, and just use the resulting function.
Using async...await will also make the code cleaner, however, this depends on the version of codebase you're working on. However, the sample above do works for .then as well.

sending JSON from node js to jquery client but it cannot

I try to send JSON data to client. I test typeof dataJ and it return object at console dataJ is printed dataJ=[object Object],[object Object]. At client, it displays nothing and it alert XMLHttpRequest.responseText is null and textStatus is error messages and errorThrown is null. Since it doesn't say error, I don't know what does I do wrong.
server site:
app.post('/myaction', async function (req, res) {
async function next_func(req, res) {
var myJson = await show();
return myJson;
}
dataJ = await next_func(req, res);
console.log("dataJ=" + dataJ);
console.log(typeof dataJ)
res.status(200);
res.contentType('application/json');
res.send(dataJ);
});
app.listen(8081, function () {
console.log('Server running at http://127.0.0.1:8081/');
});
async function show() {
var con = mysql.createConnection({
host: "127.0.0.1",
user: "root",
password: "aaaaaaaa",
database: "doto"
});
var sql = "select * from task_list";
resultsArray = [];
await new Promise((resolve, reject) => {
con.connect((err, connection) => {
if (err) return reject(err)
con.query(sql, (err, rows, fields) => {
if (err) return reject(err)
resolve(rows.forEach((row) => {
resultsArray.push({
detail: row.details,
status: row.status,
subject: row.subject
});
})
)
})
})
})
console.log("resultsArray" + resultsArray);
return resultsArray;
}
client site:
$.fn.ajaxShow = function (st) {
xhrct = $.ajax({
type: 'POST',,
data: {
status: st
},
url: 'http://127.0.0.1:8081/myaction',
success: function (data) {
alert("function");
$('#tb').empty();
if (data != null) {
var fotoData = $.parseJSON(data);
$(fotoData).each(function (i, obx) {
alert("fotoData");
$('#tb').append('<tr>')
.append('<td>' + obx.detail + '</td>')
.append('<td>' + obx.status + '</td>')
.append('<td>' + obx.subject + '</td>')
.append('</tr>');
});
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("XMLHttpRequest: " + XMLHttpRequest.responseText);
alert("textStatus: " + textStatus);
alert("errorThrown: " + errorThrown);
}
});
}

Unable to serve html file using 'http' module of Node.js

I am trying to serve an html page as a response to '/' request on my http server.
But somehow it's not working.
My index.html is -
<html>
<head>
<title>File Explorer</title>
<link rel='stylesheet' href='/stylesheets/style.css'/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.js"></script>
</head>
<script>
var fileExplorerApp = angular.module('explorerApp', []);
fileExplorerApp.controller("MyController", function ($scope, $http) {
var currentPath = '';
$scope.reload = function (newPath, back) {
if (back) {
currentPath = newPath;
} else {
if (currentPath === '') {
currentPath = newPath;
} else {
currentPath = currentPath + '/' + newPath;
}
}
console.log('Newpath- ' + currentPath);
$http.get('http://localhost:3000/list_dir?path=' + currentPath)
.then(function (response) {
$scope.filesAndFolders = response.data;
$scope.currentPath = currentPath;
}, function (error) {
console.log('Error in $http- ' + error);
});
}
$scope.back = function () {
var prevPath = currentPath.substring(0, currentPath.lastIndexOf('/'));
console.log('Path after substring- ' + prevPath);
console.log('Prevpath when back clicked- ' + prevPath);
$scope.reload(prevPath, true);
}
$scope.reload('F:/', false);
});
</script>
<body ng-app="explorerApp" ng-controller="MyController">
<div class="ui container">
<h1 id="currentPath">Current Directory- {{ currentPath }}</h1>
<button ng-if="currentPath !== 'F:/'"
ng-click="back()"
class="ui left labeled icon button">
<i class="left arrow icon"></i>
Back
</button>
<div class="ui list">
<a class="item"
ng-repeat="item in filesAndFolders"
ng-click="reload(item.name, false)"
ng-href="{{item.type === 'file' ? '/get_file?path='+currentPath+'/'+item.name : ''}}">
<i ng-if="item.type === 'folder'" class="folder icon"></i>
<i ng-if="item.type === 'file'" class="file icon"></i>
{{ item.name }}</a>
</div>
</div>
</body>
</html>
Via angular i'm accessing another route '/list_dir' and handling the request using 'http' module of Node.js(Not Express).
if(parsedUrl.pathname === '/list_dir') {
console.log('I\'m here');
var file_path = parsedUrl.query['path'];
list_dir.listDir(file_path, function (err, data) {
if(err){
res.writeHeader(400, {'Content-Type':'text/json'});
res.write(err);
} else {
console.log('in list_dir, no errors- response is- '+data);
res.writeHeader(200,{'Contenttype':'application/json'});
res.write(JSON.stringify(data));
}
});
res.end();
break;
}
The route '/list_dir' then accesses a function in another script which is this-
module.exports = {
listDir: function (path, myCallback) {
var resultObj = [];
fs.readdir(path, function (err, data) {
console.log('In listDir');
if (err) {
switch(err.code){
case 'EACCES':
return myCallback({errno: err.errno, description: 'An attempt was made to access a file in a way forbidden by its file access permissions.'}, null);
case 'ENOENT':
return myCallback({errno: err.errno, description: 'The specified path does not exist.'});
case 'EPERM':
return myCallback({errno: err.errno, description: 'An attempt was made to perform an operation that requires elevated privileges.'})
case 'ENOTDIR':
return myCallback({errno: err.errno, description: 'The specified path is not a directory.'})
}
return myCallback(err, null);
}
var itemsCompleted = 0;
data.forEach(function (value) {
fs.lstat(path + '/' + value, function (err, stats) {
itemsCompleted++;
if (err) {
console.log(err);
} else {
if (stats.isFile()) {
resultObj.push({
type: 'file',
name: value,
size: stats['size']
});
//resultObj.push(value);
//console.log(resultObj + '\n');
} else if (stats.isDirectory()) {
resultObj.push({
type: 'folder',
name: value,
size: stats['size']
});
}
}
if (itemsCompleted >= data.length) {
//console.log(resultObj);
return myCallback(null, resultObj)
}
});
});
});
}
};
This function return a json object of all the files/folders inside the given path, which will be provided to the '/list_dir' route. But i'm not getting the correct response from the route.
I want this route to respond with the same json that is returned by the listDir function. I'm new to the http module of Node.js, maybe ive written the header wrong or i'm consuming the data in a wrong way. Please help. Thanks!
UPDATE:
Chirags answer was correct and now '/list_dir' route is returning the correct json response. However, i'm still not able to serve the index.html file where i'm using AngularJS to consume this route.
This is how i'm handling the route-
if (parsedUrl.pathname === '/') {
fs.readFile('./index.html', 'utf-8', function (err, fileResponse) {
if (err) {
console.log('Error');
res.writeHeader(404, {
"Content-Type": "text/html"
});
res.write('There was an error!');
} else {
console.log('No error');
res.writeHeader(200, {
"Content-Type": "text/html"
});
res.write(fileResponse);
}
res.end();
});
}
Whats wrong with this?
You are closing your response stream too early. Basically, res.end() gets executed before your asynchronous function to read the directory gets executed and the callback is invoked. Try:
if (parsedUrl.pathname === '/list_dir') {
console.log('I\'m here');
var file_path = parsedUrl.query['path'];
list_dir.listDir(file_path, function (err, data) {
if (err) {
res.writeHeader(400, {
'Content-Type': 'text/json'
});
res.write(err);
} else {
console.log('in list_dir, no errors- response is- ' + data);
res.writeHeader(200, {
'Contenttype': 'application/json'
});
res.write(JSON.stringify(data));
}
res.end();
});
break;
}

Returning response from https node request

I'm trying to retrieve the response(var body) from response_handler function to my /image/search route. But the problem is I cannot do it by making it (var body) a global variable since it's asynchronous.
router.get('/imagesearch/:term', (req, res) => {
let term = req.params.term;
bing_web_search(term);
res.json('trying to add json response here')
});
let host = 'api.cognitive.microsoft.com';
let path = '/bing/v7.0/search';
let response_handler = function (response) {
let body = '';
response.on('data', function (d) {
body += d;
});
response.on('end', function () {
console.log('\nRelevant Headers:\n');
for (var header in response.headers)
// header keys are lower-cased by Node.js
if (header.startsWith("bingapis-") || header.startsWith("x-msedge-"))
console.log(header + ": " + response.headers[header]);
body = JSON.stringify(JSON.parse(body), null, ' ');
console.log('\nJSON Response:\n');
console.log(body);
});
response.on('error', function (e) {
console.log('Error: ' + e.message);
});
};
let bing_web_search = function (search) {
console.log('Searching the Web for: ' + search);
let request_params = {
method : 'GET',
hostname : host,
path : path + '?q=' + encodeURIComponent(search),
headers : {
'Ocp-Apim-Subscription-Key' : subscriptionKey,
}
};
let req = https.request(request_params, response_handler);
req.end();
}

.ajax call never returns

I'm using Express and Node. I've got some code that is posting JSON to another service that is adding it in a database.
The logic is doing what it is supposed to do, but the ajax call I am making is never returning, in the 'Network' tab in Chrome Dev tools it always shows as 'Pending' and eventually errors out with net::ERR_EMPTY_RESPONSE.
Can anyone tell me where I am going wrong?
Ajax Call
$.ajax
({
type: "POST",
url: "/order",
contentType: 'application/json',
data: orderDataJson,
success: function () {
alert("success!");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("Something went wrong checking out!\n" + textStatus + "\n" + errorThrown);
}
});
This above routes to /order, which in turn posts the data to the other service:
app.post("/order", function(req, res, next)
{
var options = {
uri: endpoints.ordersUrl + "order",
method: 'POST',
json: true,
body: req.body
};
request(options, function(error, response, body) {
if (error !== null )
{
return;
}
if (response.statusCode == 200 && body != null && body != "")
{
if (body.error)
{
res.status(500);
res.end();
return;
}
res.end(); // UPDATED AFTER COMMENT
return;
}
console.log(response.statusCode);
});
});
This is the relevant code in the other service (it's correctly adding the content in the database)
if (request.method == 'POST')
{
switch (path)
{
// Add a new order
case "/order":
var body = '';
request.on('data', function (data) {
body += data;
});
request.on('end', function () {
var orderData = JSON.parse(body);
// Insert into orders table
var saleDate = getDate();
var ordersQuery = "INSERT into orders (customerId, saledate)" +
" VALUES (" + orderData.customerId +",'" + saleDate + "')";
db.query(ordersQuery, function(err, result)
{
if (err)
{
throw err;
}
var orderId = result.insertId;
// Insert order details
for (var i=0; i < orderData.order.length; i++)
{
var productId = orderData.order[i].productId;
var quantity = orderData.order[i].quantity;
var orderDetailsQuery = "INSERT into orderdetails (orderID, productID, quantity)" +
"VALUES (" + orderId + "," + productId + "," + quantity +")";
db.query(orderDetailsQuery, function(err, result)
{
if (err)
{
throw err;
}
});
}
});
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
});
break;
Try to add this in your error block:
if (error !== null ) {
res.status(500).send('Internal server error!');
return;
}
I got this fixed. The issue seem to be that express 'middleware' function should have been:
app.post("/order", function(req, res, body)
as opposed to:
app.post("/order", function(req, res, next)
From the expressjs docs:
If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.

Categories

Resources