Mongoose $push from HTML Form not working - javascript

Can anyone tell me what am I doing wrong.
My HTML Form:
<form action="/user/:id" method="put">
<div class="form-group">
<label>Miles</label>
<input type="text" class="form-control" name="miles">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
My Express Route:
app.put('/user/:id', function(req, res) {
User.findById(req.body.params.id, function(err, user) {
if (err)
res.send(err);
console.log(user.id);
User.findByIdAndUpdate(
user.id,
{$push: {"milesLog": {miles: req.body.miles}}},
{safe: true, upsert: true},
function(err, model) {
console.log(err);
},
res.json(user)
);
Posting from my HTML form I get the following Error:
Cannot GET /user?miles=66&activity=asdasd
But When I test this through POSTMAN it works:
What am I doing wrong. Why doesn't it work from my HTML Form?

The route doesn't match, you have this URL
/user?miles=66&activity=asdasd
and then this route
app.put('/user/:id', ....
that route is looking for something like this
/user/66
it doesn't look for querystrings, that would be
app.put('/user', function(req, res) {
var miles = req.query.miles;
var activity = req.query.activity;
and unless you have a really good reason for using PUT request, you should change that to use GET instead.
Also, <form action="/user/:id" ... isn't a valid URL, you can't have colons in the URL, and you seem to have misunderstood a little, the :id in your route matches anything, as long as it's a valid route, so it will match
/user/frank
/user/77
/user/something?querystring
etc. and then you can access that inside the route
app.get('/user/:id', function(req, res) {
var user = req.params.id; // returns "frank" etc

There is no "PUT" verb in html forms, while you are implementing it like this:
<form action="/user/:id" method="put">
You have to use method="POST" in html form and change your route to:
app.post('/user/:id')
It's not a bad thing to use such method.
However if you are developing a front-end application it's common to use XMLHttpRequest object which has "PUT" verb, and your route will work just fine.

Related

Trying to submit form data into database after payment is succeeded, with node js and express?

i have a project where I have a form where you can fill in a first- and last-name, and then the names will be uploaded to my MongoDB database, and then placed on another page in p-tags.
I have succeeded to get this done, however the problem is that I need a payment to be succeeded before the form data will be uploaded to my database.
Currently I have both the forms and javascript for the submit-form and the stripe-payment api.
First, I have the script for the stripe API, and I have the script for both saving and posting form data to/from db:
// routes
app.get('/', (req, res) => {
res.render('index', {
stripePublishableKey: 'pk_test_51IVfPNLNmuMLNSTmFh4R5GIZMjnTTf4mQGy5UQRTam6vfooJWhyXIrT5tIclvgydZm1EYPfN1VgBBCZAN6Las1Ap007qYaR6zr'
});
});
// charge route
app.post('/charge', (req,res)=>{
const amount = 2500;
stripe.customers.create({
email: req.body.stripeEmail,
source: req.body.stripeToken
})
.then(customer => stripe.charges.create({
amount,
description: 'coviDON',
currency: 'usd',
customer: customer.id
}))
.then(charge => res.render('success'));
});
// the page where the form data will be submitted
app.get('/wall', (req, res) => {
Covid.find().sort({ createdAt: -1 })
.then((result)=>{
res.render('wall', {covids: result})
})
.catch((err)=>{
console.log(err);
})
});
// save form data to db and post to wallsite
app.post('/wall', (req, res) => {
const covid = new Covid(req.body);
covid.save()
.then((result)=>{
res.redirect('/wall');
})
.catch((err)=>{
console.log(err);
})
});
Then, I have the index page where the two forms are placed:
<body>
<div class="create-attribute">
<form action="/wall" method="POST">
<label for="first-name">First name</label>
<input type="text" id="firstName" name="firstName" required>
<br><br>
<label for="last-name">Last name</label>
<input type="text" id="lastName" name="lastName" required>
<button>Buy</button>
</form>
</div>
<form action="/charge" method="POST">
<script
src="https://checkout.stripe.com/checkout.js"
class="stripe-button"
data-key= "<%= stripePublishableKey %>"
data-amount="2500"
data-name="Web Development Ebook"
data-description="Ebook written by Brad Traversy"
data-image="/img/marketplace.png"
data-locale="auto"
>
</script>
<script>
// hide default stripe button
document.getElementsByClassName('stripe-button-el')[0].style.display = 'none';
</script>
<button type="submit" class="btn btn-outline-dark text-white btn-lg">Purchase for 25$</button>
</form>
</body>
So, my goal and question is how I can connect these two together, so I have to press the stripe-button and pay the fee. After the payment is succeeded I want the submit-form to be processed so the data the user inputs will be stores to the db, and then posted to the wall-site in the p-tags??
First of all, it looks like you're using Legacy Checkout, which has been deprecated for years. It is recommended that you not integrate this way, and instead prefer the new Checkout. If this is an existing integration, you should consider migrating.
That said, if you want to do something like this you'll want to switch to the custom configuration and leverage the token/source function callbacks.

Cannot POST /path

I've looked through multiple post about this but can't seem to pinpoint the problem. I'm doing a donation page for an organization and need this to check if paypal is even working. It's an error between my form and app.post. Error I get is: Cannot POST /path . Can't use / because its the path for my contact form
app.get("/donate", (req, res) => res.sendFile(__dirname + "views/donate.html"));
app.post("/done", (req, res) => {
const create_payment_json = {
intent: "sale",
payer: {
payment_method: "paypal",
},
redirect_urls: {
return_url: "https://asociacioncorazondiverso.org/donate.html",
cancel_url: "https://asociacioncorazondiverso.org/donate.html",
},
transactions: [
{
item_list: {
items: [
{
name: "Donación",
sku: "001",
price: "10.00",
currency: "USD",
quantity: 1,
},
],
},
amount: {
currency: "USD",
total: "10.00",
},
description: "Donación",
},
],
};
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
throw error;
} else {
for (let i = 0; i < payment.links.length; i++) {
if (payment.links[i].rel === "approval_url") {
res.redirect(payment.links[i].href);
}
}
}
});
});
Form:
<div class="container-contact100-form-btn">
<h2>Donación de 10 USD</h2>
<form action="/done" method="post">
<button type="submit" class="btn btn-warning" value="Buy">Donación</button>
</form>
</div>
Your code as you posted on GitHub and provided in the comments on the initial question shows a striking difference between what you posted here and what you're actually working with.
Above, your <form>'s action parameter is clearly set to "/done" (which appears to be correct, as that's the path you've defined in your receiving server's code).
However, the code you seem to actually be working with is referencing /path in the same <form> element declaration:
<form action="/path" method="post">
<button type="submit" class="btn btn-warning" value="Buy">Donación</button>
</form>
Adjust the action parameter to match what you have in your question above ("/done") so your HTML document POSTs to the correct path/endpoint you've defined.
<form action="/done" method="post">
<button type="submit" class="btn btn-warning" value="Buy">Donación</button>
</form>
I saw syntax error in your server.js file on your github link for this code
app.post("/", function(request, response) {
this part is not closed properly, otherwise your code is working if you correctly use paths.
Try to keep the full api url
<form action="http://localhost:3030/done" method="post">
<button type="submit" class="btn btn-warning" value="Buy">Donación</button>
</form>
There is a brackets issue in the server.js file that you've hosted on github. The post routes are defined inside the /sendmail route. Move those outside and it should work.
Good evening what if you change you code from
app.post, app.get to
const router = express.Router();
router.get('/done', (req, res) => { // do smth });
app.use('/', router);
app.use(router);
It should work for you. Just try ;)

Pass input to url parameters in angular 2

I'm trying to pass an input from angular2 to a url parameter on a get request to retrieve data from my database. I've looked everywhere to see if anyone else has done this and while they have passed objects as parameters I'm not sure if that is what I need to do.
here's some code..
This is my backend express route to retrieve data from my mongodb.
app.get('/displayorders/:showOrder', function (req, res) {
db.woocommerceorders.findOne({ id: req.params.showOrders }, function
(err, data) {
if(err){
console.log(err);
}res.send(data);
});
})
This is my service in angular2 to retrieve data from my mongodb.
displayOrders(showOrders) {
var displayedOrders;
return this.http.get('http://localhost:3000/displayorders/:' + showOrders)
.map(res => res.json());
}
This is my front end click event to retrieve the desired parameter from the input and pass it as a parameter on my url string.
onFindOrderById(showOrders) {
this.woocommerceService.displayOrders(showOrders)
.subscribe(
data => this.showOrders = JSON.stringify(data),
error => alert(error),
() => console.log('Displaying Order By Id')
);
}
This is my html used to take the input and pass it to my click event function.
<div class="form-group container bottom-border">
<button type="button" class="btn displaybutton"
(click)="onFindOrderById(showOrders)">Click To Retrieve</button>
<br><br>
<div class="row">
<div class="col-xs-6">
<input class="form-control col-xs-6" [(ngModel)]="showOrders"
placeholder="Input Id Number">
<p><b>Retrieved Order:</b></p> <div>{{showOrders}}</div>
</div>
</div>
</div>
I'm wondering if I should try a post request instead? I feel as though this should be straight forward but right now I keep getting an error of UNEXPECTED END OF JSON ENDPOINT. Any help would be greatly appreciated.

How to convert a template from jade to HBS?

I am not too familiar with the jade template language, but quite familiar with handle bars. I need to use hbs because my project is based on hbs.
I have the following the braintree payment for nodejs express, and their view was based on jade.
https://github.com/braintree/braintree_express_example/blob/master/views/checkouts/new.jade
form#payment-form(action="/checkouts", method="post")
section
.bt-drop-in-wrapper
#bt-dropin
label(for="amount")
span.input-label Amount
.input-wrapper.amount-wrapper
input#amount(name="amount" type="tel" min="1" placeholder="Amount" value="10")
button.button(type="submit")
span Test Transaction
script(src="https://js.braintreegateway.com/js/braintree-2.27.0.min.js")
script.
(function () {
var checkout = new Demo({
formID: 'payment-form'
});
var token = "#{clientToken}";
braintree.setup(token, "dropin", {
container: "bt-dropin"
});
Below is my router
router.post('/', parseUrlEnconded, function (request, response) {
var transaction = request.body;
gateway.transaction.sale({
amount: 7,
paymentMethodNonce: transaction.payment_method_nonce
}, function (err, result) {
if (err) throw err;
if (result.success) {
[...]
I essentially want the payment form to be shown in view, and the payment_method_nonce value submitted to the server
Use jade-to-handlebars, which is a nodejs module to do exactly what you ask.

How to get value from .ejs to javascript file

I have a .ejs file, which is actually a drop down form, that fills data using sqlite3 database. Now what i want to do is, when i select a value from dropdown, i want to send it back to my javascript file, where i'd save it to database.
Normally this wasn't hard on a select statement which i made on my own, but as this select statement gets filled from javascript, the value that sends back is undefined, don't know why.
To sum up on example:
I have a user that is logged in, and has option to save a workout on a dropdown.
Workout table
ID: 5
Name: Biceps
Result
Exercise
ID:1
Name: Biceps
Workout-ID: 5
My code
Javascript to .ejs
var Workout = bookshelf.Model.extend({
tableName: 'workout'
});
var Exercise = bookshelf.Model.extend({
tableName: 'exercise',
workout: function()
{
return this.hasMany(Workout)
}
});
router.get('/', function (req, res) {
new Vaje().fetchAll().then(function (workout) {
res.render('Exercise', { workout: workout });
}).catch(function (error) {
console.log(error);
});
});
This sends all of the data from workout table into select form on .ejs
.ejs file
<h2>Select workout</h2>
<select>
<% workout.forEach(function(w) { %>
<option id=""
<%=w.attributes.id%>">
<%= w.attributes.name %>
</option>
<% }); %>
</select>
<br></br>
<form method="post">
<input type="submit" value="Add workout" />
</form>
javascript file
This file should now get selected value and save it to database...
router.post('/', function (req, res) {
var new_workout = req.body;
console.log("Workout: " + JSON.stringify(new_workout));
new Exercise().save(new_workout);
});
Result from console
I have no idea why the value is undefined/empty, but i would sure as hell like to find out.
Any help will be much appreciated!
UPDATE
UPDATE2
SOLUTION
router.post('/', function (req, res) {
new Vaje({ 'id': parseInt(req.body.naziv) })
.fetch()
.then(function (new_workout) {
if (new_workout != null)
new Trening().save({
vaje_id: new_workout.get("id"),
naziv: new_workout.get("naziv")
});
});
});
The issue is your ejs file. You have Select out of your Form.
<h2>Select workout</h2>
<form method="post">
<select name="workout">
<% workout.forEach(function(w) { %>
<option value="<%=w.attributes.id%>">
<%= w.attributes.name %>
</option>
<% }); %>
</select>
<br></br>
<input type="submit" value="Add workout" />
</form>
Edit 1
Did you add to your application (for express 3).
app.use(express.bodyParser());
Its required to process post body.
Edit 2 - solution for Express v.4
first you need to install additional package
npm install body-parser --save
later edit your app:
var express = require('express'); // <- this is your code
var bodyParser = require('body-parser');
var app = express(); // <- this is your code
app.use(bodyParser.urlencoded({ extended: false }));
// and now app listen
app.listen(8888); // <- your port here
Edit 3
How to get Name & id. It will be something like this.
router.post('/', function (req, res) {
new Workout({'id': parseInt(req.body.workout)})
.fetch()
.then(function(new_workout) {
if(new_workout != null)
new Exercise().save({
vaje_id: new_workout.get("id"),
name: new_workout.get("name")
});
});
});

Categories

Resources