Hello I am learning the basics of node. The issue im having is that I want to validate the data passed into the post request from a html form. The data is being passed in but im also getting an error in the console.
Here is the server code:
app.post('/', (req, res)=> {
const schema = Joi.object({
username: Joi.string().trim().required(),
password: Joi.string().min(3).max(10).required(),
})
const validation = schema.validate(req.body);
console.log(req.body)
if(validation.error){
console.log(validation.error)
// res.send('an error has occurred')
}
res.send('successfully posted data')
})
the console error (with sample data: username: test & password: test):
[Error [ValidationError]: "value" must be of type object] {
_original: [
{ name: 'username', value: 'test' },
{ name: 'password', value: 'test' }
],
details: [
{
message: '"value" must be of type object',
path: [],
type: 'object.base',
context: [Object]
}
]
}
I dont understand why I am getting a validation error. The req.body appears to be an object when printed to the console with console.log(req.body) but when I try to use validation it appears inside of an array? Kind of confused.
Additional Info:
I am using express.urlencoded() and express.json() if that matters.
Here is the JQuery from the HTML page:
<script>
$(document).ready(()=>{
$('#form').submit((e)=>{
e.preventDefault();
$.ajax({
url: '/',
type: 'post',
contentType: 'application/json',
data: JSON.stringify($('#form').serializeArray()),
success: (response)=>{
console.log('successfully got response');
console.log(response)
}
})
})
});
</script>
The error clearly states that req.body is an array.
[
{ name: 'username', value: 'test' },
{ name: 'password', value: 'test' }
]
From jQuery documentation page, we also have .serializeArray() method creates a JavaScript array of objects. So, you're actually sending an array of objects to the server-side and that's why you have the error.
To fix the problem, I think you should modify the frontend part. Since you already have
express.urlencoded(), you can use serialize.
<script>
$(document).ready(()=>{
$('#form').submit((e)=>{
e.preventDefault();
$.ajax({
url: '/',
type: 'post',
contentType: 'application/json',
data: JSON.stringify($('#form').serialize()),
success: (response)=>{
console.log('successfully got response');
console.log(response)
}
})
})
});
</script>
Related
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) {}
}}
I am building Web application on my localhost.
The front-end is Reactjs framework, running in localhost:3000
The back-end is nodejs + Express, running in localhost:4000
Now, I have created the API below:
router.post('/register', function (req, res) {
console.log(req.body); // {}, why it is empty?
// create new instance, save it to database
User.create(req.body).then(function () {
res.send('success');
});
});
The front-end part is:
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values); // value is not empty, I have tested! So we did send something to the API
const input = JSON.stringify({
username: values.username,
password: values.password,
});
console.log(input);
$.ajax({
url: `${API_ROOT}/register`,
method: 'POST',
data: JSON.stringify({
username: values.username,
password: values.password,
}),
}).then((response) => {
if (response === 'success') {
this.props.history.push('/login');
} else {
console.log('do not jump');
}
});
}
});
}
I have tested the API by the postman, I can add users to MongoDB, so the API is good.
I have console.log what I sent to API, it is not empty, however, backend API receive d empty request body. I have already fixed the "Access-Control-Allow-Origin" issue, so I think I do send something to the API, but backend API received empty request body.
If you add a content type header saying what type the body of the request is it should work as expected.
$.ajax({
url: `${API_ROOT}/register`,
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify({
username: values.username,
password: values.password,
})
})
I'm just new in React and NodeJS express programming and I'm stuck in some error for hours.
when I'm trying to fetch, sometimes I got a response (but not the my response)
and sometimes I got 'failed to fetch'.
I have tried to understand 'cors' concept without a lot of understanding,
but I have commit app.use(cors()) that allowed every source.
note that my server sometimes got 'OPTIONS' request, and sometimes getting 'POST' request.
in my React, I have this function:
fetch('http://localhost:3000/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify ({
user: this.state.username,
pass: this.state.password,
})
}).then(res => {
console.log(res.msg);
})
.catch(function(err) {
alert(err);
})
}
in my NodeJS I have this function:
router.post('/', (req, res) => {
let user = {
username: req.body.user,
password: req.body.pass
}
UserModel.findOne({'username': user.username, 'password' : user.password}, function(err, user) {
if (err) {
res.json({
ok: false,
msg: 'login failed, try later'
});
} else if (user) {
let token = jwt.encode(user, secret);
res.json({
msg: 'logged in',
ok: true
});
} else {
res.json({
ok: false,
msg: 'invalid input'
});
}
});
Im very confused, I hope you can help me.
Thanks.
You aren't accessing the JSON of the response correctly. You need to call the Body#json method of the response to actually access the JSON content. Also note that it returns a promise that resolves to the JSON content of a response:
fetch('…', { … })
.then(res => res.json())
.then(json => {
console.log(json.msg);
});
Also, I recommend sending an HTTP status code along with the JSON instead of having an ok property. That is a standard way and has builtin support through the Response object:
res.status(200).json({ … });
I am trying to send an email from node+express application. I am using sendgrid for sending the emails. Data for the email text is taken from the jade, supported by node. Although the email is getting delievered to the respective email, but the template is send as plain HTML(no css is getting applied).
Following is my API for sending the email:
router.post('/registered/email/send', function (req, res, next) {
var template = process.cwd() + '/views/email.jade';
fs.readFile(template, 'utf8', function (err, file) {
if (err) {
return res.send('ERROR!');
} else {
var compiledTmpl = _jade.compile(file, { filename: template });
var context = { title: 'Title text', name: req.body.name };
var html = compiledTmpl(context);
var request = sg.emptyRequest({
method: 'POST',
path: '/v3/mail/send',
body: {
personalizations: [
{
to: [
{
email: req.body.email,
},
],
subject: 'Subject',
},
],
from: {
email: 'test#gmail.com',
},
content: [
{
type: 'text/html',
value: html,
},
],
},
});
sg.API(request, function (error, response) {
if (error) {
console.log('Error response received');
} else {
res.send('success');
}
});
}
});
});
Following is my email.jade:
extends layout
block content
div.body-container
h1.title Footworks School of Dance
p Hi #{name}, title is <strong>#{title}</strong>.
I have checked my layout.jade, where i have added respective css file as well.
Is there anything else i am missing or doing incorrect ?
Some email service provider like gmail or yahoo block css link, you should use inline style in your template, use this link to see which css properties are supported by email clients
I just wrote a ultrasimple nodejs backend with basic crud operations. However on the put statement i don't receive the body of my request:
app.put('/note-update/:id', function (req, res) {
var noteId = req.params.id;
console.log(req.body)
db.collection('notes').update({
_id: noteId
}, req.body, (err, result) => {
res.send(
(err === null) ? {
msg: req.body
} : {
msg: err
}
);
});
});
Here is the call i execute with ajax:
var note = {
_id: "599e660cbc845b4e2952715f",
name: "Genauer Detailbeschrieb",
note: "Ey-10"
}
$.ajax({
type: 'PUT',
url: '/note-update/599e660cbc845b4e2952715f',
dataType: 'JSON',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(note)
})
as you can see i have a console.log(req.body) and all i get is {}
Are you using the bodyparser?
app.use(bodyParser.json());
Plz show more code for your node setup if it doesn't work.