How to send React to Express server get Request passing id - node.js

Hello I am learning on MERN Stack dev, so I am trying to implement a get request where by I send in and ID and then try searching through the collection by the id the return the entry back to the client so I have been trying to implement this but I do not know where I am going wrong because I get a 404 response
Code below is the client side where I try to send through the get request
const ProductDetails = (props) => {
const product_id = window.location.href.split("/")[4];
console.log(product_id);
const getProduct = () => {
const url = `http://127.0.0.1:5000/single-women-clothes/id?=${product_id}`;
Axios.get(url)
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.log(error);
});
};
getProduct();
return (
<div>
<h1>Details</h1>
</div>
);
};
router.get("/single-womens-clothes/:id", (request, response) => {
console.log(request.params);
MongoClient.connect(
mongoURI,
{ useNewUrlParser: true, useUnifiedTopology: true },
(error, client) => {
client
.db("OnlineStore")
.collection("WomensClothes")
.find(request.params.id)
.toArray()
.then((data) => {
response.status(200).json(data);
})
.then((response) => {
console.log("Single Female Product Fetch Successful");
})
.catch((error) => {
console.log(error);
});
}
);
});
Can I please get help on how I can pass the ID to the server then search through collection through this given ID

Anytime you have a 404 error, the issue is usually coming from putting the wrong url.
In your front-end:
single-women-clothes/id?=${product_id}
Backend
/single-womens-clothes/:id
You are missing an "s" in the front-end url in "womens"
To answer your second question:
You shouldn't do id?= just simply leave it as
single-women-clothes/${product_id}

Related

React pass params with Axios post

I want to pass a params to server using Axios.post but it didn't work with 404 error any ideas??
code:
function Movie() {
const { index } = useParams(); // get index from path /movie/:index
const [movie, setMovie] = useState([]);
useEffect(() => {
Axios.post("http://localhost:3001/movie", {
params: { id: index },
})
.then((response) => {
setMovie(response.data);
})
.catch((err) => {
console.log(err);
});
}, []);
return (
<body>
abc
{index}
{movie.id}
</body>
);
}
Server:
app.post('/movie', async (req, res)=>{
let id= req.params.id;
let movie=[];
movie.push(id);
res.send(movie);
});
A 404 Error means that the path /movie cannot be found on the API. Perhaps ensure that the route on your server is named correctly.

How to make GET request with MERN Stack

I'm trying to fetch data from database. Everything I got from response is this:
Response {type: "cors", url: "http://localhost:5000/products/", redirected: false, status: 200, ok: true, …}
I need help for how to make the request in frontend and backend:
Here is ReactJS side:
getProducts() {
fetch('http://localhost:5000/products/', {
method: "GET",
})
.then(response => console.log(response))
.then((response) => {
console.log(response.data)
this.setState({products: response.data});
})
.catch((error) => {
console.error(error);
});
}
Here is my server side for the request:
router.get('/', (req, res) => {
productService.getAll(req.query).then(products =>{
res.status(200).json(products)
}).catch(() => res.status(500).end())
})
Here is the productService:
async function getAll(query) {
let products = await Product.find({}).lean()
return products;
}
P.s.: the products are creating without errors in MongoDB Compass:
You should call response.json() to extract the JSON body from the response stream and return it to the next then block in the chain. And you can omit the method configuration since it is GET by default.
fetch('http://localhost:5000/products/')
.then((response) => response.json())
.then((products) => {
this.setState({ products })
})
Btw, you shouldn't hardcode the API URL. Use environment variables. If you're using Create React App, you can add environment variables prefixed with REACT_APP_ to .env or you can use dotenv-webpack if you have a custom Webpack setup.
fetch(`${process.env.BASE_API_URL}/products`)
.then((response) => response.json())
.then((products) => {
this.setState({ products })
})

After post request a post not appearing immediately

I have a Node backend with React frontend. When a user creates a movie review, the post request gets handled with axios. Right after that, the user gets taken to a homepage but the review is not there yet. When I refresh the page, the review appears.
How can I fix this issue so that the user doesn't have to get confused when, after submitting, they don't see the review in homepage? Should I refetch every time a user hits the homepage? Or is React doing it behind the scenes but early so the review isn't registered?
My redux request code:
the reducer
export const postNewReview = review => (dispatch, getState) => {
return apiCall("post", `http://localhost:8000/review`, review)
.then(res => {})
.catch(err => addError(err.message));
};
the api call function
export function apiCall(method, path, data){
return new Promise((resolve,reject) => {
return axios[method.toLowerCase()](path,data)
.then(res => {
return resolve(res.data);
})
.catch(err => {
return reject(err.response.data.error);
});
});
}
handling submitting
handleSubmit = (e) => {
e.preventDefault();
this.props.postNewReview(this.state);
this.setState({user: '', title: '', image: '', text: ''});
this.props.history.push('/');
}

POST request with Axios not sending data to my server

Here is my React code for the form submission:
const handleSubmit = (e) => {
e.preventDefault();
console.log('item:', item);
Axios.post('http://<MY_SERVER>/item/add', {name:item})
.then(response => console.log(response))
.catch(err => console.log(err));
};
and this is the code in my Node API:
// Add a new Item
app.post('/item/add', (req, res) => {
const newItem = new Item({
name: req.body.name
});
newItem.save()
.then(item => {
res.json({msg: 'success'});
})
.catch(err => console.log(err));
});
When I run the handleSubmit nothing happens. I only get the console.logs... Also, here is the error from my server
'ValidationError: item validation failed: name: Path' `name` is required
So it is clear that the data sent over to the api is never received. I've tried changing it up in many ways I have came across online but no luck.
I have attached both ways to post data i.e. Form URL Encoded and JSON. For sending Form Url Encoded data we need an additional Library querystring.
You can install it using npm install query-string
Here is the code for both the requests. You don't need query-string if you are using content type application/json.
Here you go
var axios = require('axios');
const qs = require('querystring');
function sendFormUrlEncodedData() {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
const payload = {
name: 'morpheus',
job: 'leader'
};
//Send data with form url using querystring node package for it.
axios
.post('https://reqres.in/api/users', qs.stringify(payload), {
headers: headers
})
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err);
});
}
function sendJSONData() {
const headers = {
'Content-Type': 'application/json'
};
const payload = {
name: 'morpheus',
job: 'leader'
};
//Send data with JSON, so stringifying it.
axios
.post('https://reqres.in/api/users', JSON.stringify(payload), {
headers: headers
})
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err);
});
}
sendFormUrlEncodedData();
sendJSONData();
First of all check whether your backend code is working or not by using postman. I think you are getting validation error because of the error of your backend code. And also check whether that you are implemented the name attribute correctly with its data type.
After that update, the react code as below.
import axios from 'axios';
constructor() {
this.item = {
name: ''
}
}
handleSubmit(event) {
console.log('item:', this.item.name);
event.preventDefault();
axios.post('http://<MY_SERVER>/item/add', this.item)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
}

Axios does not return the error in the frontend?

I create a server on NodeJs by using Express and MongoDB (Mongoose) to create REST API after that I connect that API to my Frontend (ReactJS). the problem is that when I send post request from Axios, but on error (Duplicate Key) they not respond to catch and give a response on .then like that {data: "You Cannot Add Duplicate Link", status: 200, statusText: "OK", headers: Object, config: Object…}
FrontEnd:
axios
.post(`${SERVER}`, post) // Here Post is an object
.then(async res => {
await this.setState({ host: res.data._id });
})
.then(() => this.setState({ loading: false }))
.catch(async error => {
await this.setState({ error: error.res });
});
}
BackEnd:
const post_link_with_id = async (req, res) => {
await models
.create({
// Objects like obj_key: req.body.obj_model
})
.then(result => res.send(result))
.catch(err =>
err.code === 11000 ? res.send("You Cannot Add Duplicate Link") : ""
);
};
Make sure you are sending error status while send the response from the server.
The standard way to send a response is by using a status code.
Like,
res.status(statusCode).send(responseMessage);
For error in server, you should use the following response,
err.code === 11000 ? res.status(404).send("You Cannot Add Duplicate Link") : "";
Your final backend code should,
const post_link_with_id = async (req, res) => {
await models
.create({
// Objects like obj_key: req.body.obj_model
})
.then(result => res.send(result))
.catch(err =>
err.code === 11000 ? res.status(400).send("You Cannot Add Duplicate Link") : ""
);
};
You may want to change the suitable status code.
For details, check the documentation.
Also fix your front end setState() method, as suggested in the comments.

Resources