How to change pug after first sending it in NodeJS - node.js

Somehow, I can't seem to change anything after first sending my pug file. I have an array of image URLs and am sending it to pug and receiving it in pug like this:
function putnewvalsinpug() {
db.get('URL', function (err, value) {
if (err) return console.log('', err);
var newnewval = ""
data = value;
data = data.toString()
var stringArray = data.split(" ");
console.log(stringArray);
app.get('/', (req, res) => {
res.render('index', {imgsrcs: stringArray});
});
})
}
each image in imgsrcs
a(href=image)
img(src=image)
when I add a URL to the database, I want my website to show the additional images after a refresh, but it only shows the new images after a server restart. I have tried running putnewvalsinpug() after adding an URL to the database and not only on startup, but that did not work.

Related

how to pass JSON data into pug template without render()?

in my case, the scenario is when i click a button the value of sort, cost range and the type of Cuisine is got through the JS code then i send a post axios request from that and then passing the data from client side to server side ,where i use a controller to get the values of those data, then i send an axios GET request to the Route which is defined in my code to get the information from the database ,the problem which i face is HOW TO SEND the data from my server to frontend pug template because when i use .render() it shows internal server error in my browser but when i use .json() , i can see the output in my console ,so the problem is with my controller function i guess ? so can anyone look into my problem and provide a solution
the controller code is
exports.filter = catchAsync(async (req, res, next) => {
try {
let cost = req.query.cost;
const cuisine = req.body.params.Cuisine;
const Sort = req.body.params.sort;
let paramobj = {};
if (cuisine) {
paramobj.Cuisine = cuisine;
}
if (Sort) {
paramobj.sort = Sort.toString();
}
if (!cost) {
cost = "";
} else {
cost = `?${cost}`;
}
const data = await axios.get(
`http://localhost:3000/api/ver1/restaurant${cost}`,
{
params: paramobj,
}
);
const restaurantinloc=data.data.data
res
.status(200)
.render("restaurantcard", {
restaurantinloc,
});
// .json(restaurantinloc);
} catch (err) {
console.log(err);
}
});
everything works fine when i use res.json(restaurantinloc) but when i use res.render() i shows internal server error and not rendering the page

Mongodb display searched document data in ejs file

I am trying to make it so that if I search for a name that Mongodb would search for that document and then that it would display it in the ejs file. And it should do that by changing the text field of a H4 field in the js file at the client side. But when I try to do this it would keep saying that "Query" (which is the name of the searched data that comes back from the document) is not defined. However I only try to give the h4 that name after mongodb has done the search and has brought back that data from the query. For this I am using: Mongodb, express, EJS and nodejs.
Index.js:
router.post('/searchplayer', ensureAuthenticated, function(req, res){
const {text} = req.body;
var input = text
User.findOne({charactername: text})
.then(user => {
if(user) {
const { MongoClient } = require("mongodb");
const url = 'mongodb+srv://test:test1234#databasetest.5f9jh.mongodb.net/Databasetest?retryWrites=true&w=majority';
console.log('player found')
MongoClient.connect(url, function(error, db) {
if (error) throw error;
var dbo = db.db("Databasetest");
var query = { charactername: text };
dbo.collection("users").find(query).toArray(function(error, query, result) {
res.render('main', {
user: req.user,
query,
})
if (error) throw error;
console.log(result);
db.close();
})
});
} else {
console.log("Player does not exist")
}
})
})
Some clarification:
1: The const text is the value that people type in the ejs file.
2: Then it starts to make a search in mongodb to see if that name comes up in any of the avaible documents and returns back that certain document like this: [{charactername: "Jordan"}] which I can see back in the console log.
But now I am trying to view this data in ejs by using this script in the main.ejs:
//Search for user
document.getElementById('playersearchbtn').addEventListener('click',showotheruserpopup)
//Show other user if one is found
function showotheruserpopup() {
if (document.getElementById('searchplayerinput').value.length > 0) {
localStorage.setItem("otherusermenu","open")
document.getElementById('otheruserpopup').style.visibility = "Visible"
var userField = document.getElementById('otherusername')
userField.textContent = "<%= query%>"
localStorage.setItem('userField', userField.textContent)
var retrieveduserField = localStorage.getItem('userField')
userField.textContent = retrieveduserField
} else {
alert('You have to search something..')
}
}
//Close other user popup
document.getElementById('otheruserbtn').addEventListener('click',closeotheruserpopup)
function closeotheruserpopup() {
document.getElementById('otheruserpopup').style.visibility = "Hidden"
}
The situation is that first off the otherusername textcontent element is empty at the start but once it has done this search in mongodb the field text should change to the query which is the data that I got back from the mongodb search. But when I try this EJS will keep telling me that query is not defined in the script at the userField.textContent. Which I found weird because even trough this should get only triggerd by the script, but EJS will just automaticly say that it is not defined. But then I would not know how I could define because it only will exist once the actual search has been made.
How could I fix this issue?
I have found a work around for my problem, I made it render another page where it will shows the data after mongodb has searched for it. This seems to work fine.

CSV File downloads from Node Express server

I have an API backend with Node and Express. I am trying to take some filtered data from the frontend and create a CSV file and download it for the user. I have been using json2csv. I am able to create the data file correctly and when I use that file in my express route I download a file that just says undefined. At first, I thought it was an asynchronous issue, but after using a setTimeout as a test to see if that was an issue I still get the undefined data file. Console logging the "csvData" shows the correct data.
Express route to download the file.
app.post('/api/downloads/filtered', (req, res) => {
let fields = [];
fields = Object.keys(req.body[0])
const filteredData = req.body;
const json2csvParser = new json2csv({fields: fields});
const csvData = json2csvParser.parse(filteredData);
console.log(csvData)
fs.writeFile('./report.csv', csvData, (err) => {
if (err) {
console.log(err);
}
else {
console.log('created report.csv');
res.download('./report.csv');
}
})
})
I'm using Vue on the frontend, I get the file when clicking a button not sure if that is something I should include.
I ended up figuring out my issue. I found that downloading in a post request didn't seem to be possible. I needed a get request. Since the data for the file came in the request body I ended up keeping the post request to create the file and creating a separate get request to download the file this seemed to work fine but didn't find it documented anywhere so I wasn't sure if a better way exists.
app.post('/api/downloads/filtered', (req, res) => {
console.log(req.body)
let fields = [];
fields = Object.keys(req.body[0])
const filteredData = req.body;
const json2csvParser = new json2csv({fields: fields});
const csvData = json2csvParser.parse(filteredData);
console.log(csvData)
fs.writeFile('./report.csv', csvData, (err) => {
if (err) {
console.log(err);
}
else {
console.log('created report.csv');
}
})
})
app.get('/api/downloads/filtered', (req, res) => {
setTimeout(() => {res.download('./report.csv')}, 1000)
})

NodeJS Multiparty file upload to Azure and a text field

I need to verify that a mongodb document exists before continuing with Azure file upload.
The form consists of a file and a text field, the logic that is needed is the following:
Form submission
Get the text field
Search in mongodb for a document with the text field data
If the item exist continue with file upload to Azure else return
File upload to Azure
Save the URL to the file in the same MongoDB document that was found in
The problem I'm facing is that I can't touch field data in form.on('part') and can't get it to work with using form.parse first.
This is my code, I'm willing to change libraries and do whatever it takes to get it working.
var form = new multiparty.Form();
var formField = "";
form.parse(req, function(err, fields, files) {
formField = fields.fieldinform[0];
});
console.log(formField); //empty async?
model
.findOne({ name: formField })
.then(obj => {
form.on("part", function(part) {
if (!part.filename) return;
var size = part.byteCount;
var name = part.filename;
var container = "test";
blobService.createBlockBlobFromStream(
container,
name,
part,
size,
function(error) {
if (error) {
console.log("failed");
}
}
);
});
})
.catch(e => {
//do not continue
});
Help would be highly appreciated!
After a lot of searching and not coming up with a proper answer I decided to go with jquery that changed the action URL of the form to /upload/textintextfield before submission and then grab that with req.params.textfield in node.
<script>
$('#fileUploadForm').submit(function() {
$('#fileUploadForm').attr('action', '/upload/addvideo/' + $('#textfield').val())
return true;
});
</script>

Sending Many Requests Hangs in Node

I'm connecting to the Riot API to obtain images from their data dragon services using the Request package. Once the Request gives me a response, I save the image onto the disk. Saving champion thumbnails is a cinch; no problems. However, item thumbnails have been failing 95% of the time. It only occasionally works on my local machine.
I've been deploying the app to Heroku and the images were all successfully loaded the 4/4 times I deployed. Unfortunately, as stated earlier, when I run the server locally, my internet actually hangs and I become unable to use the internet only when I try to obtain the item thumbnails.
Here is a snippet:
function retrieveAndProcessImage(imageURL, callback) {
"use strict";
console.log(imageURL);
request(imageURL, {encoding: 'binary'}, function (req_err, req_res) {
// Extract the image name by looking at the very end of the path.
var pathArray = (imageURL).split('/');
var imageName = pathArray[pathArray.length - 1];
if (req_err) {
console.log("Couldn't retrieve " + imageName);
} else {
callback(imageName, req_res['body']);
}
});
};
The above snippet obtains the image from the API. When it occasionally works, the proper image is saved so I at least know that the URLs are all correct. The callback is just an fs.writeFile that writes the file locally so I don't have to send another request.
function retrieveAndProcessJson(dataURL, callback) {
"use strict";
request(dataURL, function (req_err, req_res) {
// Try to parse the JSON.
try {
var bodyJSON = JSON.parse(req_res['body']);
} catch (err) {
_errorMessage(dataURL);
return;
}
// If the parsing failed or the retrieval failed, connection failed.
if (bodyJSON['status'] !== undefined) {
_errorMessage(dataURL);
return;
}
// Otherwise output the success.
console.log("Connected to " + dataURL);
// Callback.
callback(req_res['body']);
});
};
The above obtains the raw JSON and passes the result of it to a callback.
fileFuncs.retrieveAndProcessJson(dataURL, function (raw_body) {
var bodyJSON = JSON.parse(raw_body);
_saveData(raw_body);
_saveImages(bodyJSON['data'])
});
and save images is:
function _saveImages(dataJSON) {
var filePath;
var itemKey;
var item;
var imageURL;
var imageName;
// Check to see the destination folder exists, and create if it doesn't.
fileFuncs.checkFolder(api_constants.itemThumbnailPath);
// For each item in the item JSON, save the thumbnail.
for (itemKey in dataJSON) {
if (dataJSON.hasOwnProperty(itemKey)) {
item = dataJSON[itemKey];
// The image are saved as #{id}.png
imageName = item['id'] + '.png';
imageURL = api_constants.itemThumbnailURL + imageName;
// Retrieve the file from the API.
fileFuncs.retrieveAndProcessImage(imageURL, function (fileName, image) {
filePath = api_constants.itemThumbnailPath + fileName;
fs.writeFile(filePath, image, { encoding: 'binary' }, function (err) {
if (err) {
console.log("\t" + fileName + " already exists.");
return;
}
console.log("\tThumbnail " + fileName + " was saved.");
})
});
}
}
}
I'd rather not have to deploy to Heroku each and every time I want to see what the changes in my code look like. Are there any solutions where I could potentially put some time between each request? Alternatively, just something that would let me do mass amounts of requests without hanging my internet.

Resources