POST http://localhost:3000/api/message 400 (Bad Request) xhr.js:210 - javascript

declared Post request but it showing error "bad request .i want to send the message and restore all the old message but now i am not able to send the Post request:
const sendMessage = async(event) => {
if(event.key === "Enter" && newMessage) {
try {
const config ={
headers:{
"Content-Type": "application/json",
Authorization: `Bearer ${user.token}`,
},
};
setNewMessage("");
const {data} = await axios.post("/api/message", {
content: newMessage,
chatId: selectedChat,
}, config);
console.log(data);
setMessages([...messages, data])
} catch (error) {
toast({
title: "Error Occured!",
description: "Failed to send the Message",
status: "error",
duration: 5000,
isClosable: true,
position: "bottom",
});
}
}
};
the Message controller declared in backend as shown below and it contains the separate chatId and content but the frontend api is not directing to this showing it as error:
const sendMessage = asyncHandler(async(req,res) =>{
const { content , chatId} = req.body;
if(!content || !chatId) {
console.log("Invalid data passed into request");
return res.sendStatus(400);
}
var newMessage = {
sender : req.user._id,
content: content,
chatId:chatId,
}
try {
var message = await Message.create(newMessage);
message = await message.populate("sender" ,"firstname pic");
message = await message.populate("chat").execPopulate();
message = await User.populate(message,{
path: "chat.users",
select:"firstname pic email",
});
await Chat.findByIdAndUpdate(req.body.chatId, {
latestMessage:message,
});
res.json(message);
} catch (error) {
res.status(400);
throw new Error(error.message);
}
});
chat Routes in serverjs to route the chat from backend to frontend given as:
app.use("/api/message",messageRoutes);

Related

Why does a put after my post, remove the last added data in my json file

In my backend is something happening, which I can't understand. If I'm registering a new User, it's working fine, and I can see the new User in my JSON File, but if I'm doing a put request after that to change my own user's data he deletes the new User which I made before?
My put request from my frontend:
//Changing user Data
export async function changeData(id, body) {
try {
await axios.put(`http://localhost:8000/users/${id}`, body, {
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem('auth._token.local')
}
});
return true;
}
catch (e) {
return false;
}
}
My endpoint in my node backend for registering a user and changing data of a user
// Register New User
server.post('/register', (req, res) => {
console.log("register with request body", req.body)
const {username, password, firstname, lastname, roles} = req.body
if(!username || !password || !firstname || !lastname || !roles) {
const status = 400
const message = "Bad Request, make sure all properties are set in request body"
res.status(status).json({status, message})
return
}
if (req.headers.authorization === undefined || req.headers.authorization.split(' ')[0] !== 'Bearer') {
const status = 401
const message = 'Error in authorization format'
res.status(status).json({status, message})
return
}
// Send only token part to admin check
if(!isAdmin(req.headers.authorization.split(' ')[1])) {
const status = 401
const message = 'Only permitted by admin'
res.status(status).json({status, message})
return
}
if(isAuthenticated({username, password}) === true) {
const status = 401
const message = 'Email and Password already exist'
res.status(status).json({status, message})
return
}
fs.readFile("./users.json", (err, file) => {
if (err) {
const status = 401
const message = err
res.status(status).json({status, message})
return
}
// Get current users data
const data = JSON.parse(file.toString())
// Get the id of last user
const last_item_id = data.users[data.users.length - 1].id
//Add new user
data.users.push({id: last_item_id + 1, username: username, password: password, firstname: firstname, lastname: lastname, roles: roles}) //add some data
const writeData = fs.writeFile("./users.json", JSON.stringify(data), (err, result) => { // WRITE
if (err) {
const status = 401
const message = err
res.status(status).json({status, message})
}
})
})
res.status(201).json({status: 201, message: "Successfully created"})
})
// handle changing user data
server.use((req, res, next) => {
console.log('Entering Users')
if(req.method === 'PUT' && req.url.includes("/users")) {
if(req.body) {
const decodedToken = jwt.decode(req.headers.authorization.split(' ')[1])
const userList = JSON.parse(fs.readFileSync('./users.json', 'UTF-8'))
const userinfo = userList.users.find((user) => user.id === decodedToken.id)
if(!req.body.password) {
req.body.password = userinfo.password
}
// if admin made the request, he should be able to change roles
if(req.body.roles && decodedToken.roles && decodedToken.roles.includes("admin")) {
console.log("Able to change");
next()
return
}
req.body.roles = decodedToken.roles
} else {
res.status(400).json(
{
status: 400,
message: "Bad request, make sure all properties are set in request body"
}
)
return
}
}
next()
})
The only thing i noticed is that after the register comes, the JSON file gets to a one-liner, but I don't think that this is the problem. It seems like the put works with an old user List? I'm not sure. Thanks in forward.

Getting following error while fetching data in react Uncaught (in promise) TypeError: Failed to fetch

I have create backend using express and mongodb database. I am trying to fetch data in react but getting an error while fetching the data as show. Please can anyone tell what the solution of above error is and how can i fetch data from the backend
const Register = () => {
const [values, setValues] = useState({
name: "",
age: "",
country: "",
email: "",
});
const setData = (e) => {
console.log(e.target.value);
const { name, value } = e.target;
setValues((val) => {
return {
...val,
[name]: value,
};
});
};
const addData = async (e) => {
e.preventDefault();
const { name, age, country, email } = values;
const res = await fetch("/register", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name,
age,
country,
email,
}),
});
const data = await res.json();
console.log(data);
if (res.status === 404 || !data) {
console.log("Error");
} else {
console.log("Data added successfully");
}
};
Here below is the backend code where the post function is performed.
router.post("/register", async (req, res) => {
const { name, age, country, email } = req.body;
if (!name || !age || !country || !email) {
res.status(404).send("Some data is missing");
}
try {
const preuser = await Crud.findOne({ email: email });
console.log(preuser);
if (preuser) {
res.status(404).send("The user already exists");
} else {
let addUser = new Crud({
name,
age,
country,
email,
});
addUser = await addUser.save();
res.status(201).json(addUser);
console.log(addUser);
}
} catch (error) {
res.status(404).send(error);
}
});
await fetch leads to an exception when the HTTP status is ≥ 400. You must add a try-catch block to handle such exceptions:
try {
const res = await fetch("/register", {...});
} catch(exception) {
// Handle the exception
}
Also, HTTP status 404 should be used when a resource is not found. You use it when a user already exists (where status 400 would be more appropriate) or in case of a database error (when 500 would be more appropriate).

why does 400 status code result always entercatch block execution with axios?

I have a contact me form in my frontend with three fields -> name, email, message. which are being passed to backend using axis
if the user doesn't enter any of the one value, it should show "please fill all the details" which is coming from backend. But here in my case in browser console.log i am seeing this error
POST https:/api-endpoint/contactMe 400
try-catch block catch error:
Error: Request failed with status code 400
at createError (createError.js:16:1)
at settle (settle.js:17:1)
at XMLHttpRequest.handleLoad (xhr.js:62:1)
If all the fields are entered it results in successful message from backend which is "thank you for contacting jatin" - this works perfectly well
Why 200 status code msg from backend is working and why 400 status code msg from backend results in error? Is this an issue with axios that for 400 or error status code it will raise exception?
Here is my react code
const handleName = (e) => {
setName(e.target.value);
};
const handleEmail = (e) => {
setEmail(e.target.value);
};
const handleMessage = (e) => {
setMessage(e.target.value);
};
const submitForm = async (e) => {
e.preventDefault();
try {
let data = {
name,
email,
message,
};
setBool(true);
console.log(data);
const res = await axios.post(
'https:/api-endpoint/contactMe',
data
);
console.log(res);
if (name.length === 0 || email.length === 0 || message.length === 0) {
console.log('hihi');
setBanner(res.data.msg);
toast.error(res.data.msg);
setBool(false);
} else if (res.status === 200) {
setBanner(res.data.msg);
toast.success(res.data.msg);
setBool(false);
setName('');
setEmail('');
setMessage('');
}
} catch (error) {
console.log(error);
}
};
my backend route
app.post('/contactMe', async (req, res, next) => {
const data = req.body;
if (
data.name.length < 1 ||
data.email.length < 1 ||
data.message.length < 1
) {
return res.status(400).json({ msg: 'Please fill all the fields' });
}
const params = {
Destination: {
ToAddresses: ['reciever#gmail.com'],
},
Message: {
Body: {
Text: { Data: `${data.message}` },
},
Subject: {
Data: `Hiring interest from "${data.name}" : "${data.email}"`,
},
},
Source: 'sender#gmail.com',
};
try {
const data = await ses.sendEmail(params).promise();
console.log(data);
return res.status(200).json({ msg: 'Thank you for contacting Jatin!!!' });
} catch (error) {
console.log(error);
return res.status(500).json({ msg: 'Service Unavailable' });
}
});
Perhaps this approach might help you?
const handleName = (e) => {
setName(e.target.value);
};
const handleEmail = (e) => {
setEmail(e.target.value);
};
const handleMessage = (e) => {
setMessage(e.target.value);
};
const submitForm = async (e) => {
e.preventDefault();
let data = {
name,
email,
message,
};
setBool(true);
console.log(data);
const res = await axios.post(
'https:/api-endpoint/contactMe',
data
).then(res => { // Response handler
console.log(res);
setBanner(res.data.msg);
toast.success(res.data.msg);
setBool(false);
setName('');
setEmail('');
setMessage('');
}).catch(error => { // Error handler
console.log(error);
setBanner(error.response.data.msg);
toast.error(error.response.data.msg);
setBool(false);
});
};
Even though #Simon's solution did worked for me
As per comments, axios default behavious to raise error for status codes other than 2xx.
So a clever way would be to just change status code on server side.
changing 400 with 200 and 200 with 201 also helped me.

Fetch API response with react and Express.js won't show any result with console.log

I have a login form that sends data to an Express.js backend using fetch. On the client side, when I want to display the results of the fetch call when it completes nothing is displayed (and it never reaches the data callback). I don't seem to be getting any errors, but I know that the data is successfully being sent to the backend.
Here's the Express.js server code:
const express = require('express');
const User = express.Router();
const bcrypt = require('bcrypt');
const user = require('../Models/user');
this is edited
function loginRouteHandler(req, res) {
user.findOne(
{
where: {
userName: req.body.userName,
},
},
)
.then((data) => {
if (bcrypt.compareSync(req.body.password, data.password)) {
req.session.userName = req.body.userName;
req.session.password = req.body.password;
console.log(req.session);
res.status(200).send('Success!');
} else {
res.status(400).send('some text');
}
});
}
User.route('/').get(getRouteHandler);
User.route('/register').post(postRouteHandler);
User.route('/login').post(loginRouteHandler);
module.exports = User;
And here's the fetch call:
fetch('http://localhost:4000/login',{
method: 'POST',
headers: {
'Accept': 'application/json,text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({
userName: this.state.userName,
password: this.state.password,
}),
}).then((response)=>{
if(response.ok){
console.log(response)
}
else {
console.log("a problem")
}
}).then((data)=>{
console.log(data)
});
In your loginRouteHandler, if the bcrypt compare succeeds nothing is returned in the response. So in the first branch of the if statement, put res.send('Success!') or something similar.
Here's an example:
function loginRouteHandler(req, res) {
user.findOne(
{
where: {
userName: req.body.userName,
},
},
)
.then((data) => {
if (bcrypt.compareSync(req.body.password, data.password)) {
req.session.userName = req.body.userName;
req.session.password = req.body.password;
console.log(req.session);
res.status(200).send('Success!');
} else {
res.status(400).send('some text');
}
});
}
UPDATE: you're also not getting the output of the fetch response with .text() or .json(). You have to update the fetch call to the following:
fetch(/* stuff */).then((response)=>{
if(response.ok){
console.log(response)
}
else {
console.log("a problem")
}
return response.text()
}).then((data)=>{
console.log(data)
});
Remove ok from response.ok
Remove .then((data)=>{ console.log(data) });
And check console log.
}).then((response)=>{
if(response){
console.log(response)
}
else {
console.log("a problem")
}
}).then((data)=>{
console.log(data)
});

Calling Facebook Messenger API in a synchronous fashion

I'm using the Facebook Messenger API to create a very basic chatbot. I want to be able to send a series of messages in individual bubbles. However, when I call the API multiple times in the same function. I can't be sure which message will show first. How can I use async/await functionality to correctly order the messages?
Function call initially:
const getStartedProcess = async(formattedText,senderID) => {
const firstMessage = await sendTextMessage(senderID,"First message");
const secondMessage = await sendTextMessage(senderID,"Second message");
const thirdMessage = await sendTextMessage(senderID,"Third message");
}
Helpers:
const sendTextMessage = async(recipientId, messageText) => {
//format message correctly
const sent = await callSendAPI(messageData);
return 0;
}
const callSendAPI = async(messageData) =>{
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: messageData
}, function (error, response, body) {
//Proccess
return 0;
});
}
How about this:
const sendTextMessage = (recipientId, messageText) => {
return new Promise((resolve, reject) => {
//format message correctly
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token: PAGE_ACCESS_TOKEN},
method: 'POST',
json: messageData
}, (error, response, body) => {
if (error) {
reject(error);
} else {
resolve(response);
}
});
})
}
const getStartedProcess = async(formattedText, senderID) => {
try {
const firstMessage = await sendTextMessage(senderID, 'First message');
const secondMessage = await sendTextMessage(senderID, 'Second message');
const thirdMessage = await sendTextMessage(senderID, 'Third message');
} catch (error) {
console.log(error);
}
}

Categories

Resources