422 Unprocessable Entity Error after fetch POST request - node.js

I'm receiving a 422 Unprocessable Entity, invalid inputs error when making a fetch POST request. This resulted in an empty object {} in my Request Payload.
I've done the following checks. Please take a look and kindly guide me in the right direction.
• checked post-routes
router.post(
'/',
[
check('location').not().isEmpty(),
check('caption').not().isEmpty()
],
postsControllers.createPost
);
• checked posts-controller, extracting correct attributes from body
const { userId, location, caption } = req.body;
const createdPost = new Post({
userId,
location,
imageUrl: 'abc.jpeg',
caption,
})
• checked if managing userId in front-end auth-context
// auth-context
export const AuthContext = createContext({
isLoggedIn: false,
userId: null,
login: () => {},
logout: () => {}
});
// App.js
const login = useCallback((uid) => {
setIsLoggedIn(true);
setUserId(uid);
}, []);
const logout = useCallback(() => {
setIsLoggedIn(false);
setUserId(null);
}, []);
• checked if user property is mapped to user object in signup and login
// signup action of users-controllers
res.status(201).json({ user: createdUser.toObject({ getters: true })});
// login action of users-controllers
res.json({ message: 'Logged in!', user: existingUser.toObject({ getters: true })});
• checked if url, request, body and headers are included when sending request in new post
// New Post
<Formik
initialValues={‌{ location: '', caption: ''}}
validationSchema={validationSchema}
onSubmit={(values, { setSubmitting }) => {
try {
fetch('http://localhost:5000/api/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
userId: auth.userId,
email: values.email,
password: values.password
})
)
history.push('/');
} catch (err) {}
}}

Related

Why is req.body empty {} (GET REQUEST)

This is my Frontend code
const fetchData = () => {
const options = {
method: 'GET',
url: 'http://localhost:1337/user/chart',
headers: {'x-access-token': sessionStorage.getItem('token')},
body: [chartData.datasets]
}
axios.request(options).then((response) => {
console.log(response)
}).catch((error) => {
console.error(error)})
}
This is backend
app.get('/user/chart', async (req, res) => {
const token = req.headers['x-access-token']
if (!token){
return res.status(404).json({ success: false, msg: "Token not found" });
}
try {
const decoded = jwt.verify(token, process.env.access_secret)
const email = decoded.email
await User.updateOne(
{ email: email },
{ $set: {} },
)
console.log(req.body)
return res.status(200).json({message: 'ok', label:[]})
} catch (error) {
console.log(error)
res.json({ status: 'error', error: 'invalid token' })
}
})
When I console.log(req.body) it is an empty {}.
Why is it empty?
I am using a GET request to retrieve the chart data
Axios API does not accept body on get get request you can send parameters with params example
const url = '/user/chart';
const config = {
headers: {'x-access-token': sessionStorage.getItem('token')},
params:{someKey:chartData.datasets}
};
axios.get(url, config)
Axios doesn't support setting a body for a get request, see the docs or this related question.
Though, I'd also recommend to reconsider your design. Typically the body isn't used in a GET request. If you're sending data to the server, you likely want to use POST or PUT instead. If you just want to pass a parameter, then you likely want to use request parameters.
If you absolutely need to send a body in your GET request, then you'll need to use a different tool.
frondend //
const fetchData = () => {
const options = {
method: 'POST',
url: 'http://localhost:1337/user/chart',
headers: {'x-access-token': sessionStorage.getItem('token')},
body: {name : "xx",mail:"xx#"}
}
axios.request(options).then((response) => {
console.log(response)
}).catch((error) => {
console.error(error)})
}
backend //
app.post('/user/chart', async (req, res) => {
const {name , mail} = req.body
const token = req.headers['x-access-token']
if (!token){
return res.status(404).json({ success: false, msg: "Token not found" });
}
try {
const decoded = jwt.verify(token, process.env.access_secret)
const email = decoded.email
await User.updateOne(
{ email: email },
{ $set: {} },
)
console.log(req.body)
return res.status(200).json({message: 'ok', label:[]})
} catch (error) {
console.log(error)
res.json({ status: 'error', error: 'invalid token' })
}
})Ï

Issue with next-auth on AWS Docker Deployment

I have used next-auth for Authentication in my next.js project and have deployed it on AWS server using DOcker. I am getting "http://localhost:3000/api/auth/error?error=Something%20went%20wrong!%20Please%20try%20again%20later." in responce of network everytime when I try to login or register and on all the pages where I have uset nextauth.
This is my nextauth code:
[...nextauth.js]
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import { API_BASE_URL } from '../../../utils/constants';
export default NextAuth({
providers: [
CredentialsProvider({
id: 'credentials',
name: 'Busfabrik',
credentials: {
email_id: {
label: 'email',
type: 'email',
},
password: { label: 'Password', type: 'password' }
},
async authorize(credentials, req) {
const payload = {
email_id: credentials.email_id,
password: credentials.password,
isadmin: !!credentials.isadmin
};
const res = await fetch(API_BASE_URL + '/users/login', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json'
},
});
const user = await res.json();
// console.log('user', user);
// If error and we don't have user data, return error
if (!res.ok) {
throw new Error(user.exception);
}
// If no error and we have user data, return it
if (res.ok && user.success) {
return user;
} else {
// Return error if user data could not be retrieved
throw new Error(user.msg);
}
},
}),
// ...add more providers here
],
secret: process.env.JWT_SECRET,
callbacks: {
async jwt({ token, user }) {
// console.log('jwt user', user)
if (user && user.success) {
return {
...token,
accessToken: user.payload.token,
userData: user.payload
};
}
return token;
},
async session({ session, token }) {
// console.log('session', session);
// console.log('session token', token);
session.accessToken = token.accessToken;
session.user = token.userData;
return session;
},
},
theme: {
colorScheme: 'auto', // "auto" | "dark" | "light"
brandColor: '', // Hex color code #33FF5D
logo: '/vercel.svg', // Absolute URL to image
},
// Enable debug messages in the console if you are having problems
debug: process.env.NODE_ENV === 'development',
});
Can someone suggest or have aced the same issue? If Yes, then please guide me on this. I an stuck here from a long time and not able to find the solution.

Error only shows at the back-end but not correctly at the front-end

I am trying to make sure that the front-end of my app will display the error that I want it to display. I am purposely trying to create a user that already exists and therefore show my custom User already exists. Please log in. error.
It shows in postman when sending a request to the same endpoint, but at the front-end, the response just shows the following and not the actual error message I defined:
Response {type: 'cors', url: 'http://localhost:8000/api/user/create', redirected: false, status: 409, ok: false, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 409
statusText: "Conflict"
type: "cors"
url: "http://localhost:8000/api/user/create"
[[Prototype]]: Response
The createUser controller:
export const createUser = async (req: Request, res: Response) => {
const { email, password } = req.body;
const existingUser = await User.findByEmail(email);
if (existingUser) {
return res.status(409).send('User already exists. Please log in.');
}
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = new User(email, hashedPassword);
const saveToDb = await newUser.saveToDb();
if (!saveToDb) {
return res.status(500).send('Could not insert user into the database.');
}
const token = newUser.signToken();
res.status(201).json({ token, id: saveToDb.insertedId });
};
The front-end submission:
const onSubmit: SubmitHandler<CreateAccountFormInputs> = async (formData) => {
try {
setLoading(true);
const res = await fetch('http://localhost:8000/api/user/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData),
});
console.log(res); // output shown above
if (!res.ok) {
setError(`HTTP error: ${res.status}`);
return;
}
navigate('/login');
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
}
Inside the if (!res.ok) block, I want to set the error to the custom message that should be returned by the API. But I can't set it if it's not returned.
Does anyone know what I'm doing wrong here?

Get an error: missing authentication using hapi-auth-jwt2

this my routes code
const Joi = require('joi')
const handler = require('../handler/get-request')
const route = {
method: 'POST',
path: '/IB',
options: {
tags: ['api', 'IB', 'request'],
description: 'Request New User IB',
notes: 'It will return new user IB data',
validate: {
payload: {
data: Joi.object().keys({
cifNo: Joi.string().min(5).max(45).required(),
userId: Joi.string().min(5).max(45).required(),
deviceInfo: Joi.string().min(3).max(45).required()
})
}
},
plugins: {
'hapi-swagger': {
responses: {
'200': {
description: 'Success'
}
}
}
},
auth: 'ib'
},
handler
}
module.exports = route
and this is my code where i registered the plugin hapi-auth-jwt
await server.register(require('hapi-auth-jwt2'))
server.auth.strategy('ib', 'jwt', {
key: config.internalServiceAccessToken,
validate: async function (decoded, request) {
// See https://github.com/dwyl/hapi-auth-jwt2
// provides checking for invalidated token after user logout
request.auth.decoded = decoded
const user = await request.server.methods.services.ib.auth.findUser(decoded.username)
return { isValid: user, credentials: decoded }
},
verifyOptions: { algorithms: ['RS256'] }
})
when i hit my routes, i got this error message, "Error: Missing Authentication".
Can someone explain me why? and help me to fix this error. Big Thanks!

FormData POST request throws Network error

I have a react native app that allows users to upload images to the server along with additional data.
I'm using NodeJS and ExpressJS as my backend framework. The route for posting images:
router.post("/", checkAuth, upload.single("gallery_item_image"), function (req, res, next) {
Branch
.findById({ _id: req.body.branch_id })
.exec()
.then((doc) => {
if(!doc) {
return res.status(404).json({
message: "Invalid Branch ID",
})
}
galleryItem = new GalleryItem({
_id: mongoose.Types.ObjectId(),
branch_id: req.body.branch_id,
caption: req.body.caption,
description: req.body.description,
imageUrl: "https://someurl.com/" + req.file.filename,
imageId: req.file.id,
})
return galleryItem.save()
})
.then((response) => {
console.log(response);
res.status(201).json({
message: "Gallery item successfully added to the database",
galleryItem: {
_id: response._id,
branch_id: response.branch_id,
caption: response.caption,
description: response.description,
date: response.date,
imageUrl: response.imageUrl,
imageId: response.imageId,
meta: {
type: "GET",
url: "https://someurl.com/" + response._id,
}
}
})
})
.catch((error) => {
console.log(error);
res.status(500).json({
error: error
})
})
})
I'm using axios to make ajax calls and the function that is making these calls looks like this:
submit = async() => {
if(this.state.imagePicked && this.state.title.length > 0 && this.state.description.length > 0) {
this.setState({
isLoading: true
})
try {
console.log(`submit()----> getting user data from AsyncStorage...`)
let data = await AsyncStorage.getItem(CONSTANTS.ASYNC_STORAGE.USER)
data = JSON.parse(data)
console.log(`submit()----> user received from AsyncStorage: ${JSON.stringify(data)}`)
const formData = new FormData();
formData.append('gallery_item_image', this.state.imageData);
formData.append("branch_id", data.branchId)
formData.append("caption", this.state.title)
formData.append("description", this.state.description)
let apiResponse = await axios({
method: 'post',
url: CONSTANTS.API.GALLERY,
data: formData,
config: {
headers: {
'Content-Type': 'multipart/form-data'
}
}
})
let apiResponseJson = await apiResponse.json()
console.log(`submit()----> axios response: ${JSON.stringify(apiResponseJson)}`)
// const config = {
// method: 'POST',
// headers: {
// Authorization: data.authToken,
// 'Content-Type': 'multipart/form-data'
// },
// body: formData,
// };
// console.log(`submit()----> posting data to API: ${JSON.stringify(formData)}`)
// try {
// let response = await fetch(CONSTANTS.API.GALLERY, config)
// console.log(`submit()----> response from API: ${JSON.stringify(response)}`)
// this.setState({
// isLoading: false,
// isModalVisible: false
// })
// } catch(error) {
// console.log(`submit()----> error occured when posting data to API: ${error}`)
// this.setState({
// isLoading: false,
// error: true,
// errorMessage: `error occured when posting data to API: ${error}`
// })
// return;
// }
this.setState({
isLoading: false
})
} catch(error) {
console.log(`submit()----> error occured when getting data from AsyncStorage: ${error}`)
this.setState({
isLoading: false,
error: true,
errorMessage: error
})
return;
}
return;
} else {
console.log(`submit()----> empty field found`)
return;
}
return;
}
However, I always get "Network Error" without any explanation.
console output
Application output

Resources