Can't send a submit fetch request - javascript

I searched for a long time without results about this question. The problem is that when I try to send an asynchronous request to another web page I don't have any response. I think the problem is where the FormData takes its values but I don't know why... Here is the code:
const addBooking_form = document.getElementById("form_addResa");
addBooking_form.addEventListener("submit", (event) => {
event.preventDefault();
// Send asynchronous request to /api/booking/new
const formData = new FormData(addBooking_form);
const searchParams = new URLSearchParams(formData);
console.log(formData);
console.log(searchParams);
const asyncReqAdd = fetch("api/booking/new", {
method: "POST",
body: formData
});
asyncReqAdd.then(response => {
return console.log(response.text() == 'undefined' ? 'Fetch reponse <=> undefined' : response);
}).then((response) => {
console.log(response)
table.innerHTML = response;
});
return console.log('New booking submited');
})
I know that the link and the form id are correct...
HTML FORM :
<form id="form_addResa">
<div class="fieldset flexCol-around">
<label for="input_lieu">Lieu *</label>
<select id="input_lieu" name="place">
<option value="none">< Séléctionner un lieu ></option>
<option value="Salammbô">Salammbô</option>
<option value="Pergola">Pergola</option>
<option value="Salon Jaune">Salon Jaune</option>
<option value="1001 Bougies">1001 bougies</option>
</select>
<div class="flexRow-around">
<div class="flexCol-around">
<label for="input_date">Date *</label>
<input id="input_date" type="date" name="date">
</div>
<div class="flexCol-around">
<label for="input_time">Heure *</label>
<input id="input_time" type="time" name="time">
</div>
</div>
<label for="input_nom">Nom *</label>
<input id="input_nom" type="text" name="name">
<label for="input_prenom">Prénom *</label>
<input id="input_prenom" type="text" name="firstName">
</div>
<div class="fieldset flexCol-around">
<label for="input_couverts">Nombre de couverts *</label>
<input id="input_couverts" type="number" name="coverts">
<label for="input_intExt">Client interne / externe *</label>
<select name="intExt" id="input_intExt">
<option value="ext">Externe</option>
<option value="int">Interne</option>
</select>
<label for="input_contacte">Contacter le client *</label>
<input id="input_contacte" type="text" placeholder="Numéro de chambre / téléphone / E-mail" name="contact">
</div>
<div class="fieldset">
<textarea id="input_note" placeholder="Note :" name="notes"></textarea>
</div>
<div class="flexRow-around">
<input type="reset" value="Annuler" style="background: white;">
<input type="submit" onclick="unselectBooking();">
</div>
</form>
Can you give me a solution for this?

You could use async/await with a try catch block to see what goes wrong.
Something like this (pseudo):
addBooking_form.addEventListener("submit", async (event) => {
event.preventDefault();
const { date, time, name, place } = Object.fromEntries(new FormData(event.target))
try {
const respone = await fetch("api/booking/new", {
method: "POST",
body: { date, time, name, place }
});
const data = await response.json()
// do something with data
console.log(data)
} catch(e) {
// do some error handling
console.log('error', e)
}
})
Update: you can use Object.formEntries on FormData to get the values of your named input fields and then pass them to the body. This way, you should have valid JSON data.
I also removed the element selector since you already got the element via event

Related

AXIOS POST form submit to WordPress returning 200 with data returning 0

I have a contact form which I am trying to POST the data via AXIOS using formData to send email via WP_mail.
Submitting the form seems to be working in the sense of:
The page isn't refreshing/adding parameters to the url
Using for (var value of formData.values()) {console.log(value);} to check what values are being grabbed by formData, console.log shows the different input values
response.status is showing 200
The problems start with response.data returning 0 rather than the data from the form that is being submitted.
This is my form
<form class="js-process dark-form">
<fieldset>
<label for="name">First name*</label>
<input type="text" name="name" placeholder="Enter your first name" />
<label for="last-name">Last name*</label>
<input type="text" name="last-name" placeholder="Enter your last name" />
<label for="email-address">Email address*</label>
<input type="email" name="email-address" placeholder="Enter your email address" />
<label for="telephone">Telephone*</label>
<input type="tel" name="telephone" placeholder="Enter your phone number" />
</fieldset>
<fieldset>
<label for="enquiry-form">Nature of enquiry*</label>
<!-- TEMP -->
<select id="enquiry-form" name="enquiry-form" data-label-value="test">
<option disabled value="">test</option>
<option value="test">test</option>
<option value="test">test</option>
<option value="test">test</option>
</select>
<label for="your-message">Your message*</label>
<textarea name="your-message" placeholder="Please tell us your message"></textarea>
</fieldset>
<input type="submit" value="Submit">
</form>
This is my JS to POST the form data
import axios from 'axios';
const processForm = (e) => {
const form = e.target;
e.preventDefault();
// let formData = new FormData(form);
const formData = new FormData();
// Console.log all formData values for testing
for (var value of formData.values()) { console.log(value); }
formData.append('action', 'contact_form');
formData.append('first_name', 'my first name');
axios({
method: 'POST',
url: WP.ajax,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: formData,
})
.then(function (response) {
console.log(response);
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
},
(error) => {
console.log(error);
});
return false;
};
const initProcessForm = () => {
const forms = document.querySelectorAll('.js-process');
forms.forEach(form => {
form.addEventListener('submit', processForm);
});
};
export default initProcessForm;
I'm not sure what I am missing here to get the data from the form to POST correctly. I know i've not even got round to the WP_mail side of things! I am new to using AXIOS so if anyone can point me in the right direction with this code or has a better way of doing this i'd be grateful to know : )
Thanks in advance.

Native checkout WooCommerce - AJAX issue

I am developing a custom plugin for WooCommerce using viva payments. The documentation is here. It will be a native plugin
https://github.com/VivaPayments/API
The issue
Currently I have to dequeue the wc-checkout script to get it to work
wp_dequeue_script( 'wc-checkout' );
The reason for dequeue is that viva uses a card handler, and using onblur events makes XHR requests to viva. Looking in the network tab the XHR request called is
https://demo.vivapayments.com/api/cards/installments?key=mykey
and the response is {"MaxInstallments":0}
If i don't deqeue the script this request isn't made. If the request isn't made when I try and get the token I get served an error saying "Expiration date could not be parsed"
Here is the jscode
function getToken(){
VivaPayments.cards.requestToken( function(){
});
}
function tokenMyFunction() {
VivaPayments.cards.requestToken( function(){
//do something?
});
}
$(document).ready(function (){
if (viva_params.testMode === '1'){
var url = "https://demo.vivapayments.com"
} else {
url = "https://www.vivapayments.com"
}
VivaPayments.cards.setup({
publicKey: viva_params.publishableKey,
baseURL: url,
cardTokenHandler: function (response) {
//console.log(response)
if (!response.Error) {
//console.log(response.Token)
$('#hidToken').val(response.Token);
return false;
}
else{
console.log(response);
alert(response.Error);
return false;
}
},
installmentsHandler: function (response) {
if (!response.Error) {
if (response.MaxInstallments == 0)
return;
$('#drpInstallments').show();
for(i=1; i<=response.MaxInstallments; i++){
$('#drpInstallments').append($("<option>").val(i).text(i));
}
}
else
alert(response.Error);
}
});
});
Here is the viva js from their server that is used
https://demo.vivapayments.com/web/checkout/js
Here is the form
<form action="index.php" method="POST" id="payment-form">
<div class="form-row">
<label>
<span>Cardholder Name</span>
<input class="form-field" type="text" size="20" name=”txtCardHolder” autocomplete="off" data-vp="cardholder"/>
</label>
</div>
<div class="form-row">
<label>
<span>Card Number</span>
<input class="form-field" type="text" size="20" maxlength="16" name=”txtCardNumber” autocomplete="off" data-vp="cardnumber"/>
</label>
</div>
<div class="form-row">
<label>
<span>CVV</span>
<input class="form-field" type="text" name=”txtCVV” size="4" autocomplete="off" data-vp="cvv"/>
</label>
</div>
<div class="form-row">
<label>
<span>Expiration (MM/YYYY)</span>
<input type="text" size="2" class="form-field" name=”txtMonth” autocomplete="off" data-vp="month"/>
</label>
<span> / </span>
<input type="text" class="form-field" class="lukeexpiry" size="4" name=”txtYear” autocomplete="off" data-vp="year"/>
</div>
<div class="form-row">
<label>
<select id="drpInstallments" value="0" name="drpInstallments" style="display:none"></select>
</label>
</div>
<div class="form-row">
<button type="button" onclick="getToken()">Get Token</button>
</div>
<input type="hidden" name="OrderId" value="146228" /> <!--Custom Field-->
<input type="hidden" name="hidToken" id="hidToken" /> <!--Hidden Field to hold the Generated Token-->
</form>
Like I said:
When I dequeue the wc-checkout, viva makes the request fine to api/cards/instalments and thus subsequently when I call tokenMyFunction() gets the token fine
If I don't dequeue I get an error about expiration on token request
How can I let viva still make requests alongside the wc-checkout script, or what in the hell is that call to instalments doing?
Why does that impact the token request. I can't see anywhere where the response {"MaxInstallments":0} is used again?
Any provided help is welcome.

express validator how to get req.validationErrors() to front side?

Hello and thanks for reading. I try to use express-validator. It works fine and block the post if for instance the name input is empty. But I don't know how I can get the error message on the front side. I have tried lot of things without success. Hope somebody can help and sorry for the size of the message. Here is a link to the doc of express validator if it can help ( https://express-validator.github.io/docs/ )
My code...
I have create a basic form:
<form id="sign-in">
<div class="form-group">
<label for="nom">name</label>
<input id="name" type="text" class="form-control" placeholder="name" autocomplete="family-name">
</div>
<div class="form-group">
<label for="username">username</label>
<input id="username" type="text" class="form-control" placeholder="username" autocomplete="given-name">
</div>
<div class="form-group">
<label for="email">email</label>
<input id="email" class="form-control" type="email" placeholder="monemail#gmail.com" autocomplete="email"></input>
</div>
<div class="form-group">
<label for="password">password</label>
<input id="password" class="form-control" type="password" autocomplete="current-password"></input>
</div>
<div class="form-group">
<label for="confirm-password">confirm-password</label>
<input id="confirm-password" class="form-control" type="password" autocomplete="current-password"></input>
</div>
<button type="submit" class="btn btn-primary">sign-in</button>
</form>
</section>
<footer>
</footer>
<script type="module" src="/js/sign-in.js"></script>
Then I do my fetch on the file sign-in.js:
document.getElementById('sign-in').addEventListener('submit', event => {
event.preventDefault()
const name = document.getElementById('name').value
const username = document.getElementById('username').value
...
// Use fetch to post data into the DB
window.fetch(`${config.serverHost}/sign-in`, {
method: 'post',
body: JSON.stringify({
name,
username,
...
})
}).then((res, errors) => {
if (res.status === 200) {
window.parent.location.reload()
} else if (res.status === 422) {
DONT KNOW WHAT TO DO TO GET MY ERROR MESSAGE
}
})
})
And finaly the server side:
app.post('/sign-in', (req, res, next) => {
// Start express validator //
req.checkBody('name', 'Please write your name').notEmpty()
req.checkBody('username', 'Please write your name').notEmpty()
...
const errors = req.validationErrors()
if (errors) {
SEND ME BACK MY ERROR MESSAGE
} else {
this part works fine, thank you
}
})
You have two options here depending on how your client is setup:
Use either express-flash or connect-flash to send errors back to your view. See this for the differences.
Use res.json to send back the errors object you created from validationErrors(). Be sure to set the appropriate HTTP status as well.
As I found the solution I post it, it may be useful for others.
Here is the sign-in.js file:
.then(res => {
if (res.status !== 200) {
res.json()
.then(res => errorsMessages.innerHTML = res.map(e => `<p>${e.msg}</p>`).join(''))
} else {
window.parent.location.reload()
}
})
And the code for the server:
const errors = req.validationErrors()
if (errors) {
res.status(422).json(errors)
} else {...}
Thank you Francisco for your help.

sending multiple parameters as post request in angular js to a laravel backend

Hi I am trying to submit a form data using post request in angular js. Here are the codes :
contact.html
<form class="acodehub-form" ng-submit="submit()" method="post" novalidate>
<div class="form-group first_name">
<label for="first_name">First Name</label><br>
<input type="text" id="first_name" ng-model="fname" name="fname" class="acodehub-input form-control " required tabindex="10" maxlength="40" value="" placeholder="First Name" />
<div class="errorMessage" ng-show="errorFN">First name cannot be empty</div>
</div>
<div class="form-group last_name">
<label for="last_name">Last Name</label><br>
<input type="text" id="last_name" ng-model="lname" name="lname" class="acodehub-input form-control " required tabindex="11" maxlength="40" value="" placeholder="Last Name" />
<div class="errorMessage" ng-show="errorLN">Last name cannot be empty</div>
</div>
<div class="form-group inputEmail">
<label for="email">Email</label><br>
<input type="email" id="inputEmail" ng-pattern = "regexemail" ng-model="email" name="email" class="acodehub-input form-control" required tabindex="12" value="" maxlength="40" placeholder="Email" />
<div class="errorMessage" ng-show="errorE">Please enter a valid email address</div>
</div>
<div class="form-group reason">
<label for="reason">Subject</label>
<select name="reason" ng-model="reason" id="reason" class="typeselects acodehub-input acodehub-select form-control" placeholder="What can we help you with?" tabIndex="13" required>
<option selected value="">What can we help you with?</option>
<option value="Marketing">Marketing</option>
<option value="Advertise" >Advertise</option>
<option value="Product Review">Product Review</option>
<option value="Tutorial Request">Tutorial Request</option>
<option value="Freebie Request">Freebie Request</option>
<option value="Write for us" >Write for us</option>
<option value="Sticker Request">Ask a question?</option>
<option value="Privacy Policy" >Privacy Policy</option>
<option value="Other">Other</option>
</select>
<div class="errorMessage" ng-show="errorR">Select a valid subject</div>
</div>
<div class="form-group inputDescription">
<label for="inputDescription">Tell Us More</label><br>
<textarea name="description" ng-model="description" value="" id="inputDescription" required class="form-control acodehub-input acodehub-textarea" tabindex="14"></textarea>
<div class="errorMessage" ng-show="errorD">Please tell us something about your query. Minimum 50 letters.</div>
</div>
<div>
<button type="submit" class="acodehub-btn acodehub-btn-dark"
data-ga-track="true" data-ga-group="Contact Us"
data-ga-event="Contact Us - Click to Submit Form"
data-ga-val="Submit">
Submit
</button>
</div>
</form>
controller.js
angular.module('app.controllers',[
'app.directives',
'app.factories'
]).controller('ContactController',['$scope','$http','$httpParamSerializer',function($scope,$http,$httpParamSerializer){
$scope.submit = function() {
var text = {"first_name":$scope.fname,"last_name":$scope.lname,"email":$scope.email,"reason":$scope.reason,"description":$scope.description};
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$http.post('/api/contact',$httpParamSerializer(text)).then(function (data, status, headers, config) {
alert("success");
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
},function (data, status, headers, config) {
alert("error");
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
});
}
}]);
web.php(in laravel)
Route::post('/api/contact','ContactController#submit');
contactcontroller
public function submit(Request $request) {
$this->validate($request,array(
'first_name'=>'required',
'last_name'=>'required',
'email'=>'required|email',
'reason'=>'required',
'description'=>'required|min:20'
));
$data = array(
'first_name'=>$request->first_name,
'last_name'=>$request->last_name,
'email'=>$request->email,
'reason'=>$request->reason,
'description'=>$request->description
);
Mail::queue('emails.contact',$data,function($message) use($data) {
$message->from($data['email']);
$message->to('gaurav.roy142#gmail.com');
$message->subject($data['reason']);
});
//dd($request);
//echo 'hello '.$submit;
if(count(Mail::failures())>0) {
return $request;
}else {
return $request;
}
//return $data;
}
I am getting the output in the console as:
Object {data: "<!DOCTYPE html>
↵<html ng-app="app">
↵<head>
↵ <b…rc="/app/services.js"></script>
↵</body>
↵</html>", status: 200, config: Object, statusText: "OK", headers: function}
undefined
undefined
undefined
I tried every solution provided on stackoverflow or any other website but I am not able to set it up correctly, everytime I am getting the same output as above. I know I am missing something somewhere and now I am out of any ideas how to set it up correctly. Please help me fix it up.
$http returns a promise. In case of success or error, an object containing data, status, config, statusText and headers properties (as you can see in your console log) is resolved or rejected.
So, change your code to :
$http.post('/api/contact',$httpParamSerializer(text)).then(function (response) {
alert("success");
console.log(response.data);
console.log(response.status);
console.log(response.headers);
console.log(response.config);
},function (error) {
alert("error");
console.log(error.data);
console.log(error.status);
console.log(error.headers);
console.log(config);
});

AJAX does not respond to form submission

I wrote a toy program to learn AJAX, which is to submit the user registration form to web server, however, the program on the server side cannot receive the data. I guess the error is on the following JS code using jQuery:
$(document).ready(function() {
$('#registerForm').submit(function() {
var formData = $('#registerForm').serialize();
$.post('/admin/user/signup', formData, registerResults);
},
registerResults: function() {
console.log("register success!");
} // end of registerResults
}); // end of ready
The corresponding html form is as following:
<form class="form-horizontal" role="form" id='registerForm' method='POST' action="/admin/user/signup">
<div class="form-group">
<label class="col-sm-3 control-label" for="fullname">Fullname: </label>
<div class="col-sm-5">
<input class="form-control" type='text' id="fullname" name='fullname' placeholder="Full Name" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="username">Username: </label>
<div class="col-sm-5">
<input class="form-control" type='text' id="username" name='username' placeholder="Username" />
</div>
</div>
<div class="form-group">
<input type='submit' value="Submit" class="register-form-button" form='user-create-form' />
</div>
</form>
can someone help me with my JS code using jQuery? Thanks a lot!
Like Felix said, your JavaScript syntax is invalid. Open up the JS console and refresh the page, and you'll see syntax errors.
Here's a shot at fixing it:
$(document).ready(function () {
$('#registerForm').submit(function() {
var formData = $('#registerForm').serialize();
$.post('/admin/user/signup', formData)
.done(registerResults)
.fail(registerError);
});
function registerResults() {
console.log("register success!");
}
function registerError() {
console.log("There was an error");
}
});
The registerResults function was a namespace function based on the formatting, but you only need a standard function like the below.
$(document).ready(function () {
$('#registerForm').submit(function () {
var formData = $('#registerForm').serialize();
$.post('/admin/user/signup', formData, registerResults);
});
function registerResults() {
console.log("register success!");
} // end of registerResults
}); // end of ready

Categories

Resources