Express.js: Undefined request body (base64) - javascript

I'm trying to convert the .xls table to .csv row.
I found the library that helps with such operation, its name XLSX
As the first step, I encode .xls table to base64 format.
Now I'm trying to send the post request with Postman (with base64 code as the body of the request)
But when I'm trying to console.log my req.body, I'm receiving undefined. Can you tell me where I could make a mistake in my app?
my app.js:
const express = require('express');
const dataConverter = require('./inputDataConverter');
const { errorHandler } = require('./../error/error-handler');
const app = express();
const port = process.env.PORT || 5000;
const domain = process.env.DOMAIN || '0.0.0.0';
app.post('/convert', dataConverter);
app.all('*', (req, res, next) => next('Invalid request'));
app.use(errorHandler);
app.listen(port, () => {
console.log(`Microservice runs on http://${domain}:${port}`);
});
inputDataConverter.js:
const XLSX = require('xlsx');
module.exports = (req, res, next) => {
console.log('First console.log ' + req.body);
const getWorkbook = (data) => {
let wb = null;
if (!data.type || data.type === 'base64') {
wb = XLSX.read(data.body, { type: 'base64' });
}
console.log('everything is working');
return wb;
};
const requestData = req.body;
console.log(requestData);
getWorkbook(requestData);
};

As Molda said
You may need body parser
https://www.npmjs.com/package/body-parser
On new version actually body-parser is embedded to express so you can use that like:
app.use(express.json())
I really suggest you use express-generator package to generate base Express application
https://www.npmjs.com/package/express-generator
You may find something you may not need
just strip that out

Related

How to access next.js rendered HTML via custom server

I want a server side generated page in next.js to be served as a file. So I wanted to grab the rendered content inside a custom server.js file:
const express = require('express');
const next = require('next');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({dev});
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
server.get('/', async (req, res) => {
const nextResponse = await app.renderToHTML(req, res, '/', req.query);
console.log('nextResponse', nextResponse);
console.log('res.body', res.body);
});
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
});
Oddly enough every console.log returns null or undefined.
I thought that renderToHTML would just return the rendered HTML string. Is there any way to do this?
This one is a bit tricky but achievable.
The idea is to override res.end function in order to catch rendered HTML there. The tricky part is that Next.js gzips and streams response using the compression library that's overriding res.end somewhere in the middle of the handle function.
The compression library is initialized using the handleCompression function of the Next.js's Server object (which is accessible using the app.getServer()), so that function needs to get overridden too.
So it should be looking something like this:
const { parse } = require('url');
const next = require('next');
const express = require('express');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const port = process.env.PORT || 3000;
const handle = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.get('*', async (req, res) => {
const parsedUrl = parse(req.url, true);
const nextServer = await app.getServer();
const _handleCompression = nodeServer.handleCompression.bind(nodeServer);
nextServer.handleCompression = (req, res) => {
_handleCompression(req, res);
const _resEnd = res.end.bind(res)
res.end = function (payload) {
console.log('Rendered HTML: ', payload);
return _resEnd(payload);
}
}
return handle(req, res, parsedUrl);
});
server.listen(port, err => {
if (err) throw err;
console.log('> Ready on http://localhost:' + port);
});
});
After you get rendered HTML you don't have to use the saved _resEnd function. Feel free to manipulate, serve as a file, or whatever you want with it.

How do I send image data from a url using express?

I want my the /image of my app to return a random image, how can I do that?
app.js:
const app = express();
app.get('/image', async (req, res) => {
const url = 'https://example.com/images/test.jpg';
res.send(/**/); // How do I send the image binary data from the url?
});
index.html
In HTML, this image actually shows the content of the image https://example.com/images/test.jpg
<img src="https://my-app.com/image" />
We have the same problem, and this is my solution for this using request package, so you have to yarn add request or npm i request first.
your code should be like this
const request = require('request');
const express = require('express');
const app = express();
app.get('/image', async (req, res) => {
const url = 'https://example.com/images/test.jpg';
request({
url: url,
encoding: null
},
(err, resp, buffer) => {
if (!err && resp.statusCode === 200){
res.set("Content-Type", "image/jpeg");
res.send(resp.body);
}
});
});
There is res.sendFile in Express API
app.get('/image', function (req, res) {
// res.sendFile(filepath);
});
const express = require("express");
const https = require("node:https");
const app = express();
const port = 3000
app.get("/", function(req, res){
const url = "https://api.openweathermap.org/data/2.5/weather?q=Paris&units=metric&appid=65441206f989bc53319e2689fccdc638";
https.get(url, function(response){
response.on("data", function(data){
const weatherData = JSON.parse(data)
const icon = weatherData.weather[0].icon
const imageUrl = "http://openweathermap.org/img/wn/" + icon + "#2x.png"
res.write("<img src=" + imageUrl + " ></img>")
res.send();
})
});
})
You can save all such image links in json or any of your choice data file and get from them randomly and forward and pass them through variable in response. Like: res.send(imgURL: 'https://example.com/images/test.jpg'); or you can pass url variable in init.

SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data. Why does the bodyParser not working?

This is my index.js file and i think i have placed the routes after installing bodyParser but still getting the syntax error.
const express = require('express'); //Framework to build server side application
const morgan = require('morgan'); //Logging the nodejs requests
const bodyParser = require('body-parser'); //To get the JSON data
const urls = require('./db/urls');
const app = express();
app.use(morgan('tiny'));
app.use(bodyParser.json());
app.use(express.static('./public')); //If a request comes with '/' check if file is in there if it is then serve it up.
// app.get('/', (req, res) => {
// res.send('Hello, World !!');
// });
app.post('/api/shorty', async (req, res) => {
console.log(req.body);
try {
const url = await urls.create(req.body); //Passing the body data which is JSON to create function
res.json(url);
} catch (error) {
res.status(500);
res.json(error)
}
});
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`listening on port ${port}`);
});
This is the urls.js file,I am not getting where have i messed up to make Syntax.JSON error in this file.
const db = require('./connection');
const Joi = require('joi');//Schema validation
const urls = db.get('urls');
const schema = Joi.object().keys({
name : Joi.string().token().min(1).max(100).required(),
url : Joi.string().uri({
scheme: [
/https?/ //get http 's' is optional
]
}).required()
}).with('name','url');
//almostShorty = {
// name = ,
// url =
// }
function create(almostShorty){
const result = Joi.validate(almostShorty, schema);
if(result.error === null){
return urls.insert(almostShorty);//Inserting the object in the Data Base.
}else{
return Promise.reject(result.error);
}
};
module.exports = {create};//Exporting the create function.

Res not working after receiving JSON from client

I am trying to make a simple code works, but i have a little problem that i can't understand.
So, i am trying to send to server (Express 4.16), a form in JSON, with POST method. My server receive it (i can see it with console log req.body), but none of res methods are working (it just pass through it, res.send, res.json, res.redirect... and witout any errors..).
There is my code :
app.js
const express = require('express')
const path = require('path')
const app = express()
app.use(express.urlencoded({extended: false}))
app.use(express.json())
app.use('/public', express.static(path.join(__dirname, 'static')))
app.get('/', (req,res) => {
res.sendFile(path.join(__dirname, 'static', 'index.html'))
})
app.post('/', (req,res) => {
console.log(req.body)
res.send(`You did it ${req.body.name} !! `)
})
app.listen('8080')
main.js
window.addEventListener("load", function () {
let form = document.getElementById("id-form")
function sendData() {
let XHR = new XMLHttpRequest()
let data = {}
for (const input of form.getElementsByTagName('input')) {
data[input.name] = input.value
}
XHR.open('POST', '/')
XHR.setRequestHeader('Content-Type', 'application/json')
let dataToSend = JSON.stringify(data)
XHR.send(dataToSend)
}
form.addEventListener("submit", function (event) {
event.preventDefault()
sendData()
})
})
Thanks for your help !
You are not processing the response from the server in XHR.send(dataToSend), but you should be able to see the response in the network tab on the Chrome Devtools (or its equivalent in a different browser).

Returning String with Express post

I have this app.js file:
let express = require('express')
let app = express()
let Clarifai = require('clarifai')
app.use(express.urlencoded({extended: true}))
app.use(express.static('./public'))
let link = app.post('/route', (req, res) => {
let linkString = req.body.link
res.send(JSON.stringify(linkString))
})
app.listen(3000)
const capp = new Clarifai.App({
apiKey: 'MyAPIKeyIsHere'
});
predict = capp.models.initModel({id: Clarifai.FOOD_MODEL, version: "aa7f35c01e0642fda5cf400f543e7c40"})
.then(generalModel => {
return generalModel.predict(link)
})
.then(response => {
var concepts = response['outputs'][0]['data']['concepts']
console.log(concepts)
})
console.log('Express app running on port 3000')
console.log(link)
I am trying to return a string from the app.post method but it returns a JSON file. How should I do it exactly?
You can explicitly set the content type to text/html, before sending the data.
res.set('Content-Type', 'text/html');
res.send(JSON.stringify(linkString));
Are you sure that req.body.link is a string? If yes you could just pass linkString variable in send:
let link = app.post('/route', (req, res) => {
let linkString = req.body.link
res.send(linkString)
})

Categories

Resources