I want to send an id from React to Node.js.
Here is React code:
...
<Button className='button' onClick={() => toggleButton(data)}>click</Button>
...
const toggleButton = (data) => {
fetch('http://localhost:9000/testAPI', {
method: 'POST',
body: {
id: data.id,
},
})
.then(function (response) {
return response.json();
})
.then(function (body) {
console.log(body);
});
};
and here is in Node.js (testAPI.js):
var express = require('express');
var router = express.Router();
router.post('/', function (req, res) {
console.log('req: ', req);
console.log('res: ', res);
});
it prints a lot of data in terminal log but nowhere the information sent from React.
Any suggestions?
check the root in your nodejs code. it should '/testAPI'
router.post('/testAPI', function (req, res) {
console.log('req: ', req);
console.log('res: ', res);
});
Related
I did a POST request, and I got a signal via console.log, but my array doesn't get updated. What am I missing?
CLIENT:
const handleClick = () => {
console.log("i was clicked")
fetch("http://localhost:5000/", {
method: "post",
headers: {'Accept': 'application/json',"Content-Type": "application/json"},
body: JSON.stringify(testPost),
}).then((res) => res.json())
.then(data =>{console.log("success", data)})
.catch((err) =>{console.log("rejected", err)})
};
SERVER:
let data = {
'skills': ["breathing ", "pooping"],
'awards': 2
}
app.get("/", (req, res) => {
res.json(data);
});
app.post("/", (req, res) => {
const {body} = req;
res.json(data)
console.log(body)
console.log(data)
});
I use express, cors, body-parser on the server. On the client nothing special.
my expecation: { skills: [ 'breathing ', 'pooping', 'eating' ], awards: 2 }
my results: { skills: [ 'breathing ', 'pooping' ], awards: 2 }
First, I don't know what kind of data you send to your endpoint.
So I think you send the whole object.
let data = {
'skills': ["breathing ", "pooping"],
'awards': 2
}
// ...
app.post("/", (req, res) => {
const {body} = req;
data = body // this is what you are missing
res.json(data)
console.log(body)
console.log(data)
});
What you need is to update your data object on your post request. I am assuming from your comment that your request body is like this {skills: ["eating"]}. So you may update your post api like this.
let data = {
'skills': ["breathing ", "pooping"],
'awards': 2
}
app.get("/", (req, res) => {
res.json(data);
});
app.post("/", (req, res) => {
// update skills array
data.skills = [...data.skills, ...req.body.skills];
res.json(data)
console.log(body)
console.log(data)
});
this should provide your expected result.
I saw a similar question posted Here, but they are using MEAN-Stack.
I am currently just using a 'setTimeout' function to wait a few seconds before requesting new data from the server using a fetch api to give it time to update but this doesnt feel like the right way to do it. Is there a simple way for the front-end to update only after the database is updated in Express? I am new to Node please forgive me.
app.js:
const express = require('express');
const app = express();
const mysql = require('mysql');
let viewData = {
//html data
}
var pool = mysql.createPool({
connectionLimit : 10,
host: "localhost",
port: 3306,
database: 'testing',
user: "root",
password: "pass"
});
function sql(type) {
if(type == 'select') {
//Select query here
}
if(request == 'addRow') {
//Insert query here
}
}
app.get(`/`, function (req, res) {
res.sendFile('./views/index.html', {root: __dirname});
})
app.post('/api/add', function(req, res){
res.setHeader('Content-Type', 'application/json');
sql('addRow')
});
app.get('/api/viewData', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(viewData));
})
index.js:
function loadData() {
fetch('/api/viewData')
.then(z => z.json())
.then(a => {
//update html
})
}
function postData(a) {
fetch('/api/add', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
//data to send to app.js
})
}).then(setTimeout(function(){loadData();}, 3000))
}
You should use async and await function
Example: After async/await
async function fun1(req, res){
let response = await request.get('http://localhost:3000');
if (response.err) { console.log('error');}
else { console.log('fetched response');
}
The complete code of our example is shown below:
npm install express jsonschema body-parser promise-mysql
var express = require('express');
var bodyParser = require('body-parser')
var app = express();
var validate = require('./validate')
var mysqlConnection = require('./connectionShare');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const addItem = function(item, connection){
console.log("Adding Item");
return new Promise(function(resolve, reject){
connection.query("INSERT INTO product SET ?", item)
.then(function(result){
resolve(item.seller);
}).catch(function(error){
reject(error);
});
})
}
const findOrCreateUser = function(user,connection){
console.log("Finding User");
return new Promise(function(resolve,reject){
connection.query("SELECT * FROM user WHERE email=" + connection.escape(user.email))
.then(function(results){
if(results.length == 1){
resolve(results[0].id)
} else {
connection.query("INSERT INTO user SET ?", user)
.then(function(results){
resolve(results.insertId);
});
}
}).catch(function(error){
reject(error);
})
})
}
const selectUserItems = function(userID,connection){
console.log("Selecting Items " + userID);
return new Promise(function(resolve,reject){
connection.query("SELECT * FROM product WHERE seller = " + connection.escape(userID))
.then(function(results){
resolve(results);
}).catch(function(error){
reject(error);return;
});
})
}
app.post('/add/product', validate.JsonValidation, mysqlConnection.getConnection, async function(req,res){
var connection = req.connection;
var item = {
name: req.body.name,
price: req.body.price,
width: req.body.width,
height: req.body.height,
added: req.body.added,
image: req.body.image
};
var user = {
username: req.body.seller.username,
email: req.body.seller.email,
votes: req.body.seller.votes
};
try {
item.seller = await findOrCreateUser(user,connection);
var user_id = await addItem(item,connection);
var items = await selectUserItems(user_id, connection);
connection.connection.release();
res.status(200).json(result);
} catch(error) {
res.status(500).end(error);
}
});
process.on('uncaughtException', error => console.error('Uncaught exception: ', error));
process.on('unhandledRejection', error => {console.error('Unhandled rejection: ', error));
app.listen(8000, function () {
console.log('App listening on port 8000')
});
I'm a Node, web dev and programming beginner following 'Get Programming with Node.js' by Jonathan Wexler. I've worked up to the end of the section on routing in vanilla Node, with the following code in main.js:
http = require("http"),
httpStatusCodes = require("http-status-codes"),
fs = require("fs"); // This is a node js core module which interacts with the filesystem on behalf of the app.
(router = require("./router")),
(plainTextContentType = {
"Content-Type": "text/plain",
}),
(htmlContentType = {
"Content-Type": "text/html",
}),
(pngContentType = {
"Content-Type": "image/png",
}),
(customReadFile = (file, res) => {
fs.readFile(`./${file}`, (errors, data) => {
if (errors) {
console.log("Error reading the file...");
}
res.end(data);
});
});
router.get("/", (req, res) => {
res.writeHead(httpStatusCodes.OK, plainTextContentType);
res.end("INDEX");
});
router.get("/index.html", (req, res) => {
res.writeHead(httpStatusCodes.OK, htmlContentType);
customReadFile("views/index.html", res);
});
router.get("/image.png", (req, res) => {
res.writeHead(httpStatusCodes.OK, pngContentType);
customReadFile("public/images/image.png");
});
router.post("/", (req, res) => {
res.writeHead(httpStatusCodes.OK, plainTextContentType);
res.end("POSTED");
});
http.createServer(router.handle).listen(3000);
console.log(`The server is listening on port number: ${port}`);
It works just fine for loading the /index.html file, but when I try to load /image.png (stored in the correct folder, public/images/image.png) it always crashes with the error message TypeError: Cannot read property 'end' of undefined.
This happens no matter what image I use and happens also if I move the image to another folder, such as views. I have also tried writing res.write(data); res.end() instead, also to no avail. I have also tried using an async function within fs.readFile but I don't think that should be the issue here, because fs.readFile should itself execute synchronously within the function if I understand correctly.
Edit
The code for router.js, in case that helps:
const httpStatus = require("http-status-codes"),
htmlContentType = {
"Content-Type": "text/html",
},
routes = {
GET: {
"/info": (req, res) => {
res.writeHead(httpStatus.OK, {
"Content-Type": "text/plain",
});
res.end("Welcome to the Info Page!");
},
},
POST: {},
};
exports.handle = (req, res) => {
try {
if (routes[req.method][req.url]) {
routes[req.method][req.url](req, res);
} else {
res.writeHead(httpStatus.NOT_FOUND, htmlContentType);
res.end("<h1>No such file exists</h1>");
}
} catch (ex) {
console.log("error: " + ex);
}
};
exports.get = (url, action) => {
routes["GET"][url] = action;
};
exports.post = (url, action) => {
routes["POST"][url] = action;
};
You have to pass the res object as a second argument to your customReadFile function to make it work. What you have:
router.get("/image.png", (req, res) => {
res.writeHead(httpStatusCodes.OK, pngContentType);
customReadFile("public/images/image.png"); // <-- 2nd arg missing
});
What you want to have:
router.get("/image.png", (req, res) => {
res.writeHead(httpStatusCodes.OK, pngContentType);
customReadFile("public/images/image.png", res); // <-- 2nd arg added
});
I am trying to parse info from this link on my node.js project
https://stockx.com/api/products/nike-daybreak-undercover-black?includes=market
Im able to get info when I access the link through postman and going on the url on a web browser. However when I try accessing the request through my node.js project, it is saying access is denied. Any idea why?
Thanks.
Here is my code:
const express = require('express');
const request = require('request');
const cheerio = require('cheerio');
const axios = require('axios')
const app = express();
app.get('/', function(req, res){
let shoe =req.query.shoe;
let url = 'https://stockx.com/api/products/nike-daybreak-undercover-black?includes=market'
request(url, function(error, response, html) {
if (!error) {
var $ = cheerio.load(html);
console.log(html)
res.send();
}
});
});
app.listen('8080');
console.log('API is running on http://localhost:8080');
module.exports = app;
You just need to add "User-Agent" in the header. The website from which you are trying to get the data is denying all requests without User-Agent to avoid scrapers.
const options = {
url: 'https://stockx.com/api/products/nike-daybreak-undercover-black?includes=market',
headers: {
'User-Agent': 'request'
}
};
request(options, function(error, response, html) {
console.log('err: ', error);
if (!error) {
var $ = cheerio.load(html);
console.log(html)
res.send(html);
}
});
I have tried the following code and it works
// ...
app.get('/', function(req, res){
// let shoe =req.query.shoe;
let url = 'https://stockx.com/api/products/nike-daybreak-undercover-black?includes=market'
axios({
method : 'get',
url,
headers : { withCredentials: true, 'User-Agent' : 'Postman' }
})
.then(data => {
console.log('data', data.data);
})
.catch(err => {
console.log('err', err);
})
res.send().status(200);
});
In first request I'm asking external server to provide a token. And I'm getting it. Then I would like to use it in another request. All is done in express.js. What is the best solution to provide it to the another request?
It looks like this:
const express = require('express');
const axios = require('axios');
const config = require('./config');
const app = express();
axios.post('URL1', {
email: config.email,
password: config.password,
})
.then(function(response) {
console.log(response.data.token); //here I' getting the token
})
.catch(function(error) {
console.log(error);
});
const headers = { headers: { 'Authorization': 'Token ' + token } }; //here I would like to use (for the use of a second request)
axios.get('URL2', headers)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
const PORT = process.env.PORT || 5000;
app.listen(PORT);
Of course I cannot just assign it to the variable. Thank you for helping!
You can call it in another function just as shown below.
const express = require('express');
const axios = require('axios');
const config = require('./config');
const app = express();
axios.post('URL1', {
email: config.email,
password: config.password,
}).then((response) => {
// calling function here
return handleToken(response.data.token);
console.log(response.data.token); //here I' getting the token
}).catch((error) => {
console.log(error);
});
//second request will be handled here
const handleToken = (token) => {
const headers = { headers: { 'Authorization': 'Token ' + token } };
//here I would like to use (for the use of a second request)
axios.get('URL2', headers)
.then((response) => {
console.log(response);
}).catch((error) => {
console.log(error);
});
}
const PORT = process.env.PORT || 5000;
app.listen(PORT);
It's preferable if you write a separate function to avoid callback hell.
EDIT - ROUTE WITH ASYNC/AWAIT
app.get('/', async (req, res)=>{
try {
let result = await axios.post('URL1', { email: config.email, password: config.password });
let final = await handleToken(response.data.token);
// other operations here
console.log(result);
} catch (err) {
//handle error here
console.error(err);
}
})
//second request will be handled here
const handleToken = async (token) => {
try {
const headers = { headers: { 'Authorization': 'Token ' + token } };
let response = await axios.get('URL2', headers);
return response;
} catch (err) {
throw err;
}
}