MERN - Express not receiving data from Post request - node.js

I am trying to send data from a search bar into my backend express server. However for some reason, it's not being updated.
import { useState } from "react";
import Button from 'react-bootstrap/Button';
const StockSearchBar = () => {
const [search, setSearch] = useState("Stock or Crypto Symbol");
const handleSearch = e => {
setSearch(e.target.value)
}
const handleClick = (e) => {
e.preventDefault()
console.log({search})
if (setSearch !== '') {
const searchResult = {search};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(searchResult)
};
fetch('http://localhost:3001/search', options)
.then(
() => {
console.log("Search entered");
}
);
// console.log(searchResult);
}
};
return (
<>
<div className="searchBar">
<label>Look for other Stocks or Cryptos: </label>
<input type='text' onChange={handleSearch} placeholder={search}/>
<Button variant="success" type="submit" onClick={handleClick}>Success</Button>
</div>
</>
);
};
export default StockSearchBar;
and here's the backend code
const request = require("request-promise");
const fs = require("fs");
const mongoose = require("mongoose");
const cheerio = require("cheerio");
const Stock = require("./model/Stock");
const express = require("express");
const cors = require("cors");
const cron = require('node-cron');
const app = express();
const bodyParser = require('body-parser');
//MIDDLEWARE
app.use(express.json({limit: '1mb' }));
app.use(cors());
app.use(express.static('backend'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}))
// DATABASE
app.get("/", (req, res) => {
Stock.find({}).then(
items => res.json(items)
).catch(err => console.log(err))
});
app.get("/search", (req, res) => {
console.log(req.body);
res.json({
search: req.body,
});
});
app.post("/search", (req, res) => {
console.log(req.body);
res.json({
search: req.body,
});
});
app.listen(3001, function () {
console.log("Server is running...");
});
In the front end - after clicking a button it console logs an object with the search entered.
However on the backend, all I get is json text like so:
{
"search": {}
}
It doesnt get updated even though the server is continually running. Thoughts?

Related

How to display only searched results in the browser as response

I have a MongoDB collection that I search through by using a value from an input field using the $search operator and it works, when I console log the result it shows me only those documents that match the search, but I want them to be visible on the endpoint http://localhost:3001/search as well, but currently I get all the documents listed, how can I list the result of the search? I am trying with res.send(result); but it does not work. Here is my attempt:
// Requiring the dependencies
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
require('dotenv').config();
const mongoose = require('mongoose');
const PORT = process.env.PORT || 3001;
const BASE_URL = process.env.REACT_APP_BASE_URL;
const itemRoutes = express.Router();
let Comment = require('./comment.model');
app.use(cors());
app.use(bodyParser.json());
mongoose.connect(BASE_URL, { useNewUrlParser: true })
const connection = mongoose.connection;
connection.once('open', function () {
console.log('Connection to MongoDB established succesfully!');
});
let collection = connection.collection("posts_with_tags_test");
collection.createIndex(
{
postContent: 'text',
title: 'text'
}
);
itemRoutes.route('/search').post(async (req, res) => {
let result = await connection.collection("posts_with_tags_test").find({
$text: {
$search: req.body.queryString
}
}).toArray();
res.send(result);
console.log(result)
});
app.use('/search', itemRoutes);
app.listen(PORT, function () {
console.log('Server is running on' + ' ' + PORT);
})
and here is my input field:
import React, { Component } from "react";
import axios from "axios";
class Search extends Component {
getSearchQuery = () => {
const queryString = document.querySelector(
".search-input"
).value;
axios.post("http://localhost:3001/search", {
queryString: queryString,
});
console.log(queryString)
};
render() {
return (
<div>
<input
type="text"
className="search-input"
/>
<button type="submit" onClick={this.getSearchQuery}></button>
</div>
);
}
}
export default Search;
If you just access localhost:3001/search from a browser, it won't be visible because you aren't sending the data { queryString: "sample" } to be used in the query as req.body.queryString unless you're using Postman
If you're accessing it from frontend, in your React component's getSearchQuery, try using .then() on your axios.post() to receive the response from your backend
axios.post("http://localhost:3001/search", {
queryString: queryString,
}).then(response => {
console.log(response);
console.log(response.status);
console.log(response.data);
});

express.js form post req.body is empty body {}

I have the following reactjs code and using expressjs to handle the post request. req.body always returns {} from the app. But it works in Postman.
my reactjs code snippet:
handleSubmit(e) {
e.preventDefault();
fetch(config.urlDev + '/notes', {
method: 'post',
body: { "email":"test" },
//headers: {'Content-Type':'x-www-form-urlencoded'}
headers: {'Content-Type':'application/json'}
})
.then((res) => res.json())
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
}
my expressjs code snippet:
module.exports = function (app, db) {
app.post('/notes', (req, res) => {
console.log(req.body)
console.log(req.params)
res.send(req.body)
})
}
server.js:
const express = require('express');
const MongoClient = require('mongodb').MongoClient
const bodyParser = require('body-parser')
const db = require('./config/db');
const app = express();
const port = 8000;
const cors = require('cors');
const path = require('path');
app.use(cors())
//app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:true}))
MongoClient.connect(db.url, {useUnifiedTopology: true}, (err, database) => {
if (err) return console.log(err)
const mydb = database.db('notes')
require('./app/routes') (app, mydb);
app.listen(port, () => {
console.log ("server on " + port)
})
})
postman
Try un-commenting the line
//app.use(bodyParser.json()) and it should work.
or alternatively if you are sending headers in the fetch request as headers: {'Content-Type':'x-www-form-urlencoded'} instead of headers: {'Content-Type':'application/json'} it should work.

POST request not coming through (MERN)

I'm using the MERN stack to build an application for the first time.
In order to log HTTP requests I use "morgan".
I managed to send data to mongodb which seems to be working fine. The problem is that my post request is not coming through. It says "pending" for 4 minutes, then fails.
Here's what I think is the relevant part of my code:
"server.js":
const express = require("express");
const mongoose = require("mongoose");
const morgan = require("morgan");
const path = require("path");
const cors = require("cors");
const app = express();
const PORT = process.env.PORT || 8080;
const routes = require("./routes/api");
const MONGODB_URI =
"...";
mongoose.connect(MONGODB_URI || "mongodb://localhost/app", {
useNewUrlParser: true,
useUnifiedTopology: true
});
mongoose.connection.on("connected", () => {
console.log("Mongoose is connected.");
});
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());
app.use(morgan("tiny"));
app.use("/api", routes);
app.listen(PORT, console.log(`Server is starting at ${PORT}`));
Then I've put my routes into another file "api.js":
const express = require("express");
const router = express.Router();
const Lane = require("../models/lanes");
router.get("/", (req, res) => {
Lane.find({})
.then(data => {
res.json(data);
console.log("Get request successful!");
})
.catch(error => {
console.log("Error: ", error);
});
});
router.post("/save", (req, res) => {
const data = req.body;
const newLane = new Lane();
newLane.collection.insertMany(data, err => {
if (err) {
console.log(err);
} else {
console.log("Multiple docs inserted");
}
});
});
module.exports = router;
I'm using axios to send the request. This happens after submitting a form within my application.
reducer function:
const reducer = (state, action) => {
switch (action.type) {
case "add":
axios({
url: "http://localhost:8080/api/save",
method: "POST",
data: [...state, { id: uuid(), title: action.title, tasks: [] }]
})
.then(() => {
console.log("Data has been sent to the server");
})
.catch(() => {
console.log("Internal server error");
});
return [...state, { id: uuid(), title: action.title, tasks: [] }];
The reducer is being used by my context provider component, which looks like this:
export function LanesProvider(props) {
const [lanes, dispatch] = useReducer(reducer, defaultLanes);
return (
<LanesContext.Provider value={lanes}>
<DispatchContext.Provider value={dispatch}>
{props.children}
</DispatchContext.Provider>
</LanesContext.Provider>
);
}
The "add" method inside my reducer is being called when submitting a form inside another component.
Please let me know if I can add anything to my question that would help.
Thank you in advance!
you are not sending any response back to client. Try to modify post method like
router.post("/save", (req, res) => {
const data = req.body;
const newLane = new Lane();
newLane.collection.insertMany(data, err => {
if (err) {
console.log(err);
res.send(err)
} else {
console.log("Multiple docs inserted");
res.send("Multiple docs inserted")
}
});
});

POST endpoint created with Node.js not found

I have a database in Mlab that is MongoDB that has two collections and I am trying to make a POST endpoint to which I can post whatever a user has entered in a commentbox. However I am doing something wrong, because when I test my endpoint with Postman it says 404 that the endpoint is not found. Trying to post via the commentbox does not work too ofcourse. This is the url to my post endpoint:
https://astroecstatic-express.herokuapp.com/comments. However if I run this in the browser it displays an empty array, so how come I get a 404 error when trying to POST? What am I doing wrong and how can I make my POST endpoint? Here is my node.js server:
// Requiring the dependencies
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const PORT = process.env.PORT || 3001;
const itemRoutes = express.Router();
let Comment = require('./comment.model');
app.use(cors());
app.use(bodyParser.json());
mongoose.connect("mongodb://admin:SomeUSersecretpassword.mlab.com:41968/heroku_hc9xjmcl", { useNewUrlParser: true } )
const connection = mongoose.connection;
connection.once('open', function() {
console.log('Connection to MongoDB established succesfully!');
});
// Serve static assets
if(process.env.NODE_ENV === 'production') {
app.use(express.static('build'));
}
itemRoutes.route('/').get( async (req, res) => {
let collection = connection.collection("posts");
let response = await collection.find({})
.toArray();
res.send(response);
});
itemRoutes.route('/comments').get( async (req, res) => {
let collection = connection.collection("comments");
let response = await collection.find({})
.toArray();
res.send(response);
});
itemRoutes.route('/comments')
.post((req, res) => {
res.setHeader('Content-Type', 'application/json');
let comment = new Comment(req.body);
comment.save()
.then(comment => {
res.status(200).json({comment})
})
.catch(err => {
res.status(400).send('failed')
})
});
app.use('/', itemRoutes);
app.use('/comments', itemRoutes);
app.listen(PORT, function() {
console.log('Server is running on' + ' ' + PORT);
})
and my post component:
import React, { Component } from 'react';
import axios from 'axios';
class CommentBox extends Component {
constructor(props) {
super(props);
this.path = window.location.href;
this.postId = this.path.split("/").slice(-1)[0];
}
state = {
userComments: []
}
componentDidMount() {
const fetchPosts = async () => {
const res = await axios.get('https://astroecstatic-express.herokuapp.com/comments');
this.setState({...this.state, userComments: res.data})
};
fetchPosts();
}
getCommentData = (res) => {
let today = new Date();
let dd = String(today.getDate()).padStart(2, '0');
let mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
let yyyy = today.getFullYear();
today = mm + '/' + dd + '/' + yyyy;
const commentContent = document.querySelector(".comment-box-container__div-comment-box").textContent;
axios.post('https://astroecstatic-express.herokuapp.com/comments', {title: commentContent, date: today, commentId: this.postId })
window.location.reload();
}
render() {
let currentPostComments = this.state.userComments.filter((item) => {
return item.commentId === this.postId
})
return(
<div className="comment-box-container">
<div className="comment-box-container__div">
<button className="comment-box-container__post-comment-btn" onClick={this.getCommentData}> Post Comment</button>
<div className="comment-box-container__div-comment-box" contentEditable="true"></div>
</div>
<div className="comment-box-container__show-coments-section">
{currentPostComments.map(comment =>
<section>
<h3>{comment.date}</h3>
{comment.title}
</section>
)}
</div>
</div>
)
}
}
export default CommentBox;
Here's a simple way to create both a .get() and a .post() route for /comments on a router:
itemRoutes.get("/comments", function(req, res, next) {
// code here
});
itemRoutes.post("/comments", function(req, res, next) {
// code here
});
app.use(itemRoutes);
You can also use .route() instead like this:
itemRoutes.route("/comments").get(function(req, res, next) {
// code here
}).post(function(req, res, next) {
// code here
});
app.use(itemRoutes);
And, you don't even really have a compelling case for using a router for these two routes. You could also just do:
app.get("/comments", ...);
app.post("/comments", ...);
Or
app.route("/comments")
.get(...)
.post(...);
And, not even use a router for just two top level routes.

axios making an empty request then the correct request

When i try to make a request to my server the client send two requests, the first with an empty body, and the second with the correct body
this is my server file
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const cors = require('cors');
const bodyParser = require('body-parser');
const authMiddleware = require('./app/middlewares/auth.middleware');
const db = require('./config/db');
app.use(authMiddleware);
app.use(cors({ origin: '*' }));
app.use(bodyParser.json());
db.then(res => {
require('./app/routes')(app);
});
server.listen(3210, () => {
console.log('\x1b[0m', 'Backend escutando e enviando na porta 3210');
});
this is the route file
const userController = require('../controllers/user.controller');
module.exports = app => {
app.post('/sign-up', async (req, res) => {
try {
const signUpData = await userController.signUp(req.body);
res.status(200).json(signUpData.user);
} catch (error) {
console.log(error);
res.status(400).json(error);
}
});
app.post('/sign-in', async (req, res) => {
try {
const signInData = await userController.signIn(req.body);
res.header('x-auth-token', signInData.token);
res.status(200).json(signInData);
} catch (error) {
console.log(error);
res.status(400).json(error);
}
});
};
here is my axios configuration on my react project
import axios from 'axios';
export const apiUrl = 'http://localhost:3210';
export const api = axios.create({
baseURL: apiUrl,
headers: {
common: {
'Content-Type': 'application/json'
}
}
});
the function where i do the request
export const signIn = data => {
return api
.post(`/sign-in`, data)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
};
This error only occours when the request is made via client, when i
use postman everything works fine

Resources