Sending a POST Request from a PUG FORM - Can't send data - node.js

Pug layout:
html(lang='en')
block login
form(id="login" action="/users" method="post")
input(type="text", name="username", value="", placeholder="Username")
br
input(type="password", name="password", value="", placeholder="Password")
br
input(type="submit" value="Connect")
And my JS code for the post:
router.post('/', (req, res) => {
const user = new User({
username: req.body.username,
password: req.body.password
});
user.save()
.then(data => {
res.json(data);
})
.catch(err => {
res.json({message: err})
})
});
Can't seem to think on how to send the data from the form to the actual post request. It seems like it sends the request but with no information as I get:
{"message":{"errors":{"username":{"name":"ValidatorError","message":"Path `username` is required.","properties":{"message":"Path `username` is required."
Frustrated that I can make the requests in Postman but having a hard time implementing the requests into my app.

Alright apparently my only problem was that I didn't use
router.use(express.urlencoded({
extended: true
}))
Quite frustrating.

Related

Node.js: how to create relative links to website endpoints from the server side

I'm new to Node and am having difficulty defining a relative address for a site endpoint from the server-side.
What I want to do
I'm using passport-local for session auth in Express. When the user creates a new account, I'd like to:
Create the new account in the DB
Retrieve the new user account from the DB, including its db-generated user ID
Log the user in with that info.
I've got all this working except 3. I haven't yet figured out how to take an object in Node and POST it to a relative endpoint. On my local setup, for example, I'd like to POST the returned user object to localhost:3000/login.
Axios handles the POST request fine, except when I provide "/login" as the URL, it targets the path "/mycomputer/myapp/routers/login".
Some things I've Tried
router.post("/user/create", (req, res) => {
const newUser = {
username: req.body.username,
password: req.body.password
}
createUser(newUser, (err, returnedUserObject) => {
if (err) console.log(err);
axios.post("/login", returnedUserObject)
.catch((e) => console.log(e));
});
})
I've also tried:
...
createUser(newUser, (err, returnedUserObject) => {
if (err) console.log(err);
axios.post(path.join(__dirname, "/login"), returnedUserObject)
.catch((e) => console.log(e));
});
})
Both interpret the path relative to the file system. :/
I've also tried initiating the POST request from within createUser() but I get the same result.
Any help would be appreciated - thanks!
What I usually do in my projects to configure axios base route is to create an axios instance and then use it for future requests. You can make a util file like this named axiosInstance:
import axios from 'axios';
const axiosInstance = axios.create({
baseURL: 'localhost:3000'
});
export default axiosInstance;
Then wherever you need to make axios requests, import that file and do the HTTP method on the axiosInstance, like this in your example:
import axiosInstance from 'your_path';
router.post("/user/create", (req, res) => {
const newUser = {
username: req.body.username,
password: req.body.password
}
createUser(newUser, (err, returnedUserObject) => {
if (err) console.log(err);
axiosInstance.post("/login", returnedUserObject)
.catch((e) => console.log(e));
});
})

Axios post in React front end leading to error when posting to MailerLite

I have the following component:
const WaitingListComponent = () => {
const [email, setEmail] = useState('')
const onSubmit = (e) => {
e.preventDefault()
axios.post("/api/waiting-list/addToList", {
email: email
})
}
return (
<form className="waiting-list-component-container" onSubmit={onSubmit}>
<h4 className="waiting-list-component-heading">Join our waiting list to get early access</h4>
<p className="waiting-list-component-paragraph">Join our waiting list to get exclusive early access to our platform when we're ready to launch.</p>
<input className="waiting-list-component-input" name="email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="janedoe#email.com" />
<GeneralButton type="submit" text="Get access" />
</form>
)
}
This Axios request is getting posted via the following function:
const MailerLite = require('mailerlite-api-v2-node').default;
const mailerLite = MailerLite(process.env.MAILER_API);
module.exports = (req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
const email = req.body.email;
mailerLite.addSubscriberToGroup(process.env.MAILER_GROUP, email)
.then(() => {
console.log("Successfully sent new subscriber to MailerLite.");
res.send(JSON.stringify({ success: true }));
})
.catch((err) => {
console.log("There was an error.");
console.log(err);
res.send(JSON.stringify({ success: false }));
});
};
This is a post to a website called 'MailerLite'.
Their documentation is here: https://developers.mailerlite.com/docs/getting-started-with-mailerlite-api
And the package I'm using to post via node is here: https://www.npmjs.com/package/mailerlite-api-v2-node#addsubscribertogroupgroupid-subscriber
I'm attempting to use the 'addSubscriberToGroup' function to add a new subscriber to my group.
However, despite the Axios post successfully going through - as shown in the error message - there is an error being generated each time.
I don't want to post the full error because it's lengthy and it contains the API key, but the final two lines indicate it's an Axios error:
isAxiosError: true
Can anyone point out where I'm going wrong here?
If you need more info, or have any specific questions, please let me know!
The issue is probably that you need to send email as an object. You could do it like this: addSubscriberToGroup('id', { email: email })

How to resolve Mongoose broken authentication

Hey this should be very simple for you nodejs gods, I am trying to make authentication system with nodejs using mongoose so the server is successfully receiving the email and parameters entered in the front-end but it seems as if somewhere in my in my logic I am not doing everything properly can I please get some assistance in handling this error because what happens when I console log on the back-end I get the following.
User Successfully Found
EMAIL: test1#gmail.com
PASSWORD: test1
SIGNINUSER: undefined
I get that User Successfully found even when I entered a wrong user
**Interesting part is when I remove the .then I get back the user object but return errors with regards to unhandled promise
Code below where I am handling the signing in of users
router.post("/signin", async (request, response) => {
const signinUser = await User.find({
email: request.body.email,
password: request.body.password,
})
.then((response) => {
console.log("User Successfully Found");
})
.catch((error) => {
console.log("User Does not exist");
});
//Here I was trying to check if I really am receiving the data from the client
//Just to find that I am receiving the clients data
console.log("EMAIL: ", request.body.email);
console.log("PASSWORD: ", request.body.password);
//Here I was trying to check if the usersInfo is being set inside the siginUser variable
//just to find that I getting the value of undefined
console.log("SIGNINUSER: ", signinUser);
if (signinUser) {
response.status(200).json({
_id: signinUser.id,
name: signinUser.name,
email: signinUser.email,
isAdmin: signinUser.isAdmin,
token: getToken(user),
});
} else {
response.status(401).send({ message: "Invalid Email or Password" });
}
});
Without running the code I would say you are mixing await with then and monoogose queries. So in the proposed solution User.find() returns the query (which is not a promise but a theneable), you exec it to get a promise and await for result. Removing then but keeping your code behavior might look like.
router.post("/signin", async (request, response) => {
const signinUser = await User.find({
email: request.body.email,
password: request.body.password,
}).exec();
if (!signinUser) {
console.log("User Does not exist");
return response.status(401).send({ message: "Invalid Email or Password" });
}
console.log("User Successfully Found");
console.log("EMAIL: ", request.body.email);
console.log("PASSWORD: ", request.body.password);
console.log("SIGNINUSER: ", signinUser);
return response.status(200).json({
_id: signinUser.id,
name: signinUser.name,
email: signinUser.email,
isAdmin: signinUser.isAdm
token: getToken(user),
});
});
I hope it helps.
More info here
Mongoose - What does the exec function do?
Just change your response Code i think this problem will be Gone
return response.status(200).json({
_id: signinUser.id,
name: signinUser.name,
email: signinUser.email,
isAdmin: signinUser.isAdm,
token: getToken(user.toObject()),
});
I changed Only
token: getToken(user.toObject()),

req.body.caption return null

I have this code which send what the active user publish into mongodb id of the post + author + author ID + caption(what the author write), the code works perfectly but the problem that this statementcaption : req.body.caption,is keep returning null to mongodb and I really don't know why or how to solve this,
the code of publish is below :
router.post("/publish", function (req, res, next) {
// Generate a random id
User.findById(req.user.id, function (err, user) {
if (!user) {
req.flash('error', 'No account found');
return res.redirect('/login');
} else {
}
user.posts.push({
_id: guid.raw(),
author: user.userName,
authorID: user.id,
caption : req.body.caption,
comments: [],
likes: [],
createdAt: new Date(),
lastEditedAt: new Date()
});
user.save(err => {
if (err) throw err;
console.log("Post saved");
res.redirect("/");
});
});
});
the schema of caption is below :
caption :{type : String}
the ejs part is also below
<input
type="text"
id="caption"
name="caption"
class="form-control"
placeholder="enter your posts"
value="Share your thoughts!"
/>
MongoDB screen
Please some help,
Best Regards,
Your output from console.log(req.body) -- an empty body object -- proves beyond any doubt that no form fields are arriving at your route handler in your post.
It's possible you need to tell express to use a couple of middleware modules to parse the data in the bodies of POST requests. Try putting these two lines in your code somewhere before your call(s) to app.use('/', router).
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
These will make express populate the req.body object with the data from your forms. It chooses JSON or url-encoding based on the Content-Type: header.
Or it's possible your html (ejs) doesn't have your <input...> fields wrapped in your <form....> object. You can tell if this is true by looking at your POST request in the Network tab of your browser. You'll find a section called Form Data if you click on the POST request. If it's empty, your form post sent nothing. If the caption field is empty, that field wasn't wrapped in the <form ...> tag.

axios is not implementing post request

i am trying to post data with axios (NodeJS, ReactJS) but i ended up getting this errors
and here is my posting code
axios({
method: 'post',
url: '/api/signup',
data:
{
username: this.state.username,
name: this.state.name,
surname: this.state.surname,
email: this.state.email,
password: this.state.password,
confirm_password: this.state.confirm_password,
}
})
.then(res => res.data)
.then(url => window.location.href = url.location)
.catch(error => this.setState({errorBol: true, errorMessage: error}))
and my nodeJS code
router.post('/', async (req,res)=>{
const username = req.body.username;
const name = req.body.name;
const surname = req.body.surname;
const email = req.body.email;
const password = req.body.password;
const confirm_password = req.body.confirm_password;
console.log(username)
console.log(name)
console.log(surname)
console.log(email)
console.log(password)
console.log(confirm_password)
res.status(200).send({location: '/'})
})
i have config for /api/signup like this
router.use('/api/main', require('./sinupfilename'))
so problem is not in router.post('/')
about problem:
i am implementing post request form submission and have a validation for form and it works perfectly but it gives me an errors above when i click submit button so if anyone know clue, i will be glad to hear it
Looks like the issue is not with axios but with your render function. The above issue comes when you are trying to render any object instead of a valid react element.
The issue might be at setState for errorMessage variable. Try printing the errorMessage or typeof errorMessage for further info. It should not be an object.
The error is an javascript object if you read the official documentation for axios.
You need to extract the error message and set it in your errorMessage variable. It should work fine. As per the docs, the same can be done is this similar manner:
const err = ""
if (error.response) {
err = error.response.data
} else if (error.request) {
err = error.request.response
} else {
err = error.message
}
this.setState({errorBol: true, errorMessage: err})
Basically, any thing which needs to be rendered has to be valid react element like string, html tags, numbers but not object. So, you need to make sure that whatever is rendered, it needs to be a valid react element. You can read more about it here
Hope it helps, revert for any doubts.

Resources