sending images to Postgres using express/multer - javascript

so I am using postman to send images to a post route via express library. I get the buffer of binary stuff out of it and it doesnt allows me to handle stuff. Using body-parser would help anyway?
this is where I upload the file:
app.post('/uploads', upload.single('upload'), async (req, res) => {
const imgBuffer = req.file.buffer
console.log(imgBuffer.toString())
// await client.query('UPDATE rooms SET room = $1', [imgBuffer])
res.send()
})
this is the output I have after fire the request on postman:
this wont allow me to store anything on postgres. Well, I saw that using base64 would be better to store... I really dont know. could someone help please?

Not sure but did you search on this
new Buffer(data).toString('base64')

Related

May I have a res.json and res.sendFile together in the same api endpoint in express?

I want upload the content of an excel file into the server in order to get its data and do some stuff...
I came up with the following code, however it seems like it is not working properly as the following error displays in the console Error: Can't set headers after they are sent.
The file is getting uploaded into the folder and the json message is being displayed... However I do not know if I am going to face any issue in the future...
Actually I just need the excel data no need for the excel being uploaded... Maybe you could give me a workaround, guys...
const router = express.Router();
const storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, 'uploads/');
},
filename(req, file, cb) {
cb(
null,
`${file.fieldname}-${Date.now()}${path
.extname(file.originalname)
.toLowerCase()}`
);
},
});
const excelFilter = (req, file, cb) => {
if (
file.mimetype.includes('excel') ||
file.mimetype.includes('spreadsheetml')
) {
cb(null, true);
} else {
cb('Please upload only excel file.', false);
}
};
const upload = multer({
storage,
fileFilter: excelFilter,
});
router.post('/', upload.single('file'), (req, res) => {
var workbook = XLSX.readFile(req.file.path);
var sheet_name_list = workbook.SheetNames;
var xlData = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]]);
res.json(xlData).sendFile(`/${req.file.path}`, { root: path.resolve() });
});
May I have a res.json and res.sendFile together in the same api endpoint in express?
No, you cannot. Each of those methods, sends a complete http response (including calling res.end() which terminates the http request) and you can only send one http response to each incoming request. The particular error you're getting has to do with the res.sendFile() trying to configure the response that it's getting ready to send and finding that the http response object has already been used for sending a response and can't be used again.
Ordinarily, if you wanted to sent two different pieces of data, you would just combine them into a single Javascript object and just call res.json() on the object that contains both pieces of data.
But, sending a binary file is not something you can easily put in a JSON package. You could construct a multipart response where one part was the JSON and one part was the file. You could JSON encode binary data (though that's inefficient). I presume there are probably some modules that would help you do that, but for most clients, that isn't what they are really expecting or equipped to handle.
The only way to a proper solution is for us to understand what client/server workflow you're trying to implement here and why you're trying to send back the same file that was just uploaded. There would normally not be a reason to do that since the client already has that data (they just uploaded it).

Problem with React making Get request to Node(express)

As the title says, i have a part of my react app that tries to get some data from my database, making a select based on the value I passed to it. So im gonna go ahead and first show the code where i think the problem lies:
So first, this is the function from one of my forms that sends the request to the server, i know code is probably ugly, but i can tell from the console.logs that the parameters im sending are what i intend to send(a string called "licenciaInput"
async handleClickLicencia (event) {
event.preventDefault();
console.log(this.state);
console.log("licenciaInput: "+this.state.licenciaInput);
const datoBuscar = this.state.licenciaInput;
axios.get('http://localhost:3001/atletas/:licencia',this.state)
.then(response =>{
console.log(response)
})
.catch(error =>{
console.log(error)
})
And then, i have this function which is called in that localhost route which attempts to get "licencia", and launch a select in my postgresql db where licencia="whatever", you can see the sentence in the code:
const getAtletasByLicencia = (request, response) => {
const licencia = request.body.licenciaInput;
console.log("Request: "+request);
console.log("what the server gets: "+licencia);
// const licencia = request.licenciaInput;
const sentencia ="SELECT * FROM atleta WHERE licencia ='"+licencia+"'";
pool.query(sentencia, (error, results) =>{
if(error){
throw error
}
response.status(200).json(results.rows)
})
}
As you can see, i have console.logs everywhere, and i still cannot access whatever element i send, because i always get on the server console "undefined" value.
TLDR:How can i access the "licenciaInput" i passed from my client form to my server, i have tried request.body.licenciaInput, request.params.licenciaInput, and request.licenciaInput, but none of those seem to work
I also know i have to treat after that the data i receive from the server, but i need to solve this before looking two steps ahead. Im also really new to React and node/express, so feel free to burn me with good practices im not meeting.Thanks in advance
EDIT: Im also adding this code that i have which shows the route for my method in the server:
app.get('/atletas/:licencia', db.getAtletasByLicencia)
As #Gillespie59 suggested that i should send a POST request, but i dont think i should if im both trying to send a parameter to the server to make a select, and then send the results back to the client
Change your request to:
axios.get(`http://localhost:3001/atletas/${this.state.licenciaInput}`)
...
and your route (if you are using express) should look like this:
app.get('/atletas/:licencia', function (req, res) {
var licencia = req.params.licencia
...
})
As you are using request.body you should send a POST request with axios and add a body.

REST API JavaScript Reddit - search subreddit

I am trying to create a web page where the user can type in a subreddit name and then the webpage returns data based on that webpage like the posts, or the name of the moderators etc..
I want to create a REST api in nodejs/express.
i have done a bit of research and i think i have to get the json data from the subreddit i want and then get the relevant data...
The part i am confused is how do i start? everything i see is got to do with python but i need to do it in nodejs.
Also wont the json keep changing format... for one subreddit it will be different to another subreddit
I feel like you should check if theres an API for Reddit. Then when the user types in a subreddit, you would issue a GET request from your express route. The GET request would get the information from the Reddit API and send it back to the front.
let express = require('express');
let app = express();
app.get('/api/subredditname', (req, res) => {
//make your api request here, returning a promise hopefully
//then send your data back
.then((data) => {
res.send(data).status(200);
})
.catch((err) => {
console.log(err);
});
};

Node server to send image to cloud to be hosted

I send an image file to my node server via my react app -
I want to host these images on google cloud or similar so they have an accessible URL.
I have tried using cloudinary and google cloud but to no avail thus far!
My react-side code (shortened):
imageFile = this.state.files[0])
const formData = new FormData()
formData.append('file', imageFile);
sendImage(formData)
sendImage(image) {
axios.post("https://137a6167.ngrok.io/image-upload", image, {
})
.then(res => { // then print response status
console.log(res.statusText)
})
}
The file is successfully sent to my server and consoled:
app.post('/image-upload', (req, res) => {
console.log('consoling the req.body!!!!' + JSON.stringify(req.body))
})
THE CONSOLE: consoling the req.body!!!!{"1":"[object File]"}
I did try use this following cloudinary method, yet it threw errors:
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET
})
app.use(formData.parse())
app.post('/image-upload', (req, res) => {
const values = Object.values(req.files)
const promises = values.map(image => cloudinary.uploader.upload(image.path))
Promise
.all(promises)
.then(results => res.json(results))
})
this gave me the error that an unhandled error in the promise wasnt handled and i got a bit lost with where to go beyond that!
I looked at google cloud storage too but couldn't get it working! Any advice?
What I really want to do is return back to my react app the URL of the hosted image - so it can be stored in DB for the user!
If you can help at all that would be greatly appreciated, thank you.
There are couple of things you need to fix on the front end before you try to upload to any cloud.
First you need to set 'Content-Type': 'multipart/form-data' header in axios to send the file data properly.
Check this thread for more details: How do I set multipart in axios with react?
Then on the express side you need multer or some other similar library to receive the data. You can't access it from req.body. multer adds req.files for example.
https://github.com/expressjs/multer
Try there steps and then post the exact error message you are receiving from google cloud.

node.js internal message server

I am pretty new to node.js. I am working on an app able to display NFC content on a webpage. I am using nfc-pcsp package (https://github.com/pokusew/nfc-pcsc), I can easily read data on server side. Now I just would like to display the data in the webpage, but I am stuck on the logic. Here is a part of my server code:
// ### launch server for client
var http = require('http');
var html = require('fs').readFileSync(__dirname+'/custom.html');
var server = require('http').createServer(function(req, res){
res.end(html);
});
server.listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');
//######
//#launch NFC routine ######
const nfc = new NFC(); // const nfc = new NFC(minilogger); // optionally you can pass logger to see internal debug logs
let readers = [];
nfc.on('reader', async reader => {
pretty.info(`device attached`, { reader: reader.name });
// the event is correctly displayed in the console. How to update html here?
readers.push(reader);
nfc.on('error', err => {
pretty.error(`an error occurred`, err);
});
It seems to me that I need a res object to update the html page, but as I do not get any request from client, how do I update the page just based on the callback from NFC module reader? Hope my question is clear.
Thanks,
Matt
I suggest you to use the express API
command with npm CLI : npm install --save express at your root project folder in your terminal
Then, you will be able to create a route in Get, Post, Put or Delete.
Next, In your client side you will be able to call this route by a get, post or whatever with a promise, ajax request whatever you want :)
Just understand that in order to receive or send data to your server, you need an url and with Express, you can create your own url.
https://www.npmjs.com/package/express
Don't hesitate to have a look on this API, and i'm pretty sure you will find the answer to your question on your own :)

Categories