Cannot POST /path - javascript

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 ;)

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.

Using global variables properly in node.js or is there a better way of doing this?

I am trying to get a user entered amount from my checkout.html file ( below ) so that I can use it in the Stripe code on the server.js node server.
I wasn't able to get the amount field from the form to work so I disabled it and am working with console.log and variables. I was trying to make it work with a global variable passing the value.
These 2 files from the example on the Stripe website ( you select 'node' and 'html' from the page, and click 'prebuilt' also )
https://stripe.com/docs/checkout/integration-builder
My alterations
( sorry the var assignments numbers are all just random for testing )
**server.js**
( lines 8-9 )
var test = 2242;
// console.log( amountglobal);
( line 22 )
unit_amount: test,
**checkout.html** (line 47 )
amountglobal = 67865555;
My issue is that if I uncomment line 9 ( with the aim of trying to use the amountglobal gloabal var in line 22 ) then for some reason the server wont start, saying amountglobal is not defined ... so I possibly have the global variable wrong in checkout.html, it's
amountglobal = 67865555;
... and maybe there's a better way of doing this in the first place, I understand global variables are not the ideal usually.
The end result here is to be a payment form where the user can type in their own ( previously agreed) price.
Thanks.
FULL FILES
server.js
const stripe = require('stripe')
('sk_test_51IAvl4KYIMptSkmlXwuihwZa8jtdIrnD79kSQcnhvQKbg9dbAXiZisFmasrKHIK9B75d9jgeyYK8MULLbFGrGBpU00uQgDvtnJ');
const express = require('express');
const app = express();
app.use(express.static('.'));
const YOUR_DOMAIN = 'http://localhost:4242';
var test = 2242;
console.log( amountglobal);
app.post('/create-checkout-session', async (req, res) => {
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [
{
price_data: {
currency: 'usd',
product_data: {
name: 'Stubborn Attachments',
images: ['https://i.imgur.com/EHyR2nP.png'],
},
unit_amount: test,
},
quantity: 1,
},
],
mode: 'payment',
success_url: `${YOUR_DOMAIN}/success.html`,
cancel_url: `${YOUR_DOMAIN}/cancel.html`,
});
res.json({ id: session.id });
});
app.listen(4242, () => console.log('Running on port 4242'));
Checkout.html
<!DOCTYPE html>
<html>
<head>
<title>Buy cool new product</title>
<link rel="stylesheet" href="style.css">
<script src="https://polyfill.io/v3/polyfill.min.js?version=3.52.1&features=fetch"></script>
<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<section>
<div class="product">
<img
src="https://i.imgur.com/EHyR2nP.png"
alt="The cover of Stubborn Attachments"
/>
<div class="description">
<h3>Stubborn Attachments</h3>
<h5>$20.00</h5>
</div>
</div>
<form id="frm12" action="#">
First name: <input type="text" name="amount" value = "435"><br>
<!-- <input type="button" onclick="myFunction()" value="Submit"> -->
<input type="submit" id="checkout-button" value="Checkout">
</form>
</section>
</body>
<script type="text/javascript">
function myFunction() {
console.log("test");
document.getElementById("frm1").submit();
}
// Create an instance of the Stripe object with your publishable API key
var stripe = Stripe("pk_test_51IAvl4KYIMptSkmlAwhNvG0CDJRnr2hyrJuRnfdnfaEEhHPwCWsr9QK183a1pKUQ4PLrrtEqiElFLTVHIiSueX6r00TyXooIcu");
var checkoutButton = document.getElementById("checkout-button");
var amount = document.getElementById("amount");
amountglobal = 67865555;
// console.log(amount);
checkoutButton.addEventListener("click", function () {
fetch("/create-checkout-session", {
method: "POST",
})
.then(function (response) {
return response.json();
})
.then(function (session) {
console.log('here');
return stripe.redirectToCheckout({ sessionId: session.id });
})
.then(function (result) {
// If redirectToCheckout fails due to a browser or network
// error, you should display the localized error message to your
// customer using error.message.
if (result.error) {
alert(result.error.message);
}
})
.catch(function (error) {
console.error("Error:", error);
});
});
</script>
</html>
You need to POST the data from your client side code to your server side code, and then use a JSON body parser with Express so that it ends up in the server-side request.

Axios request in Vue.js method working when launched from "mounted()" but not when launched from html <form>

When I authenticate to Laravel Passport backend with Nuxt.js like below, it works and I get a token:
mounted() {
this.axiosGetToken()
}
But, if I run the method with a button in a form, like this:
<form #submit="axiosGetToken()">
<button type="submit">Axios login</button>
</form>
Then, I get the status (canceled) for the Laravel page in the Network tab of my browser developer's tool.
The method looks like this:
axiosGetToken() {
const url = 'http://laravel.test/oauth/token'
const params = {
client_id: 2,
client_secret: 'S0gpcgfIDgbvIHCL3jIhSICAiTsTUMOR0k5mdaCi',
grant_type: 'password',
username: 'me#home.com',
password: '1qaz#WSX'
}
const headers = {
}
this.$axios
.post(url, params, headers)
.then(response => {
// eslint-disable-next-line
console.log(response)
})
.catch(response => {
// eslint-disable-next-line
console.log(response)
})
},
What's wrong with this form ?
You should add prevent modifier :
<form #submit.prevent="axiosGetToken()">
<button type="submit">Axios login</button>
</form>
by default the submit event try to reload the page and searching an action from the back-end in order to run it, so the prevent modifier will prevent the action and allows the running of the js event handler.
As mentioned above, if you use a form with a button of type="submit", when pressing that button, it will use the default client behavior and send a request to the form action URL, adding a prevent will stop that behavior.
Although it is a valid answer, I would suggest adding a #click="axiosGetToken()" on the button.
<form>
<button type="button" #click="axiosGetToken()">Axios login</button>
</form>

MeanJS stack, debugging Angular error: fnPtr is not a function

I'm learning the MeanJS stack (Mongo, Express, Angular, Node) and writing a simple todo webapp. I can list all todos and create a new one. When I 'edit' a todo, I'm encountering this error:
TypeError: fnPtr is not a function
I'm assuming I have some naming or syntax wrong (based on this and this SO question)
The problem is I don't know where to look for wrong naming or bad syntax since the file structure is pretty large ('app' and 'public' maps are 484 files). I don't get into the todo.client.controller nor 'todo.server.controller' update function, as there is a console log there that doesn't get printed. The edit button is a submit input, but I don't know where it goes next.
Code:
Piece form 'edit' page
<div class="form-group">
<input type="submit" value="Update" class="btn btn-default">
</div>
Client controller:
// Update existing Todo
$scope.update = function() {
console.log('update');
var todo = $scope.todo;
todo.$update(function() {
$location.path('todos/' + todo._id);
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
Server controller:
/**Update a Todo*/
exports.update = function(req, res) {
console.log('todo controller');
var todo = req.todo;
todo = _.extend(todo, req.body);
Todo.update({_id: req.body._id}, req.body, function(err, update) {
//todo.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(todo);
}
});
};
Anyone experienced with the MeanJS stack or Angular that could point me in a direction to start debugging?
You have not added ng-click to the "Update" submit button.
Change your code to this:
<div class="form-group">
<input type="submit" value="Update" ng-click="update()" class="btn btn-default">
</div>
As for the fnPtr error, add your full stack trace so that it can be analyzed.
Also check if your code has closed all the brackets, you are not using same name for 2 variables and typos.

Mongoose $push from HTML Form not working

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.

Categories

Resources