How to bind tokenData parameters of stripe.createToken() to inputs with ngModel - javascript

I'm trying to create charge using a token created with stripe elements on the front end. I want to add the customers address by binding the different properties of tokenData with ngmodel to inputs, then passing the tokenData object as the second argument of the createToken() method.
//component.html
<input type="text" [(ngModel)]="name" placeholder="name" name="name">
<input type="text" [(ngModel)]="address_line1" placeholder="adress line 1" name="address">
<input type="text" [(ngModel)]="address_line2" placeholder="adress line 2" name="address">
<input type="text" [(ngModel)]="address_city" placeholder="City" name="city">
<input type="text" [(ngModel)]="address_state" placeholder="State" name="state">
<input type="text" [(ngModel)]="address_country" placeholder="Country" name="country">
<button (click)="submitForm()">Submit Payment</button>
//component.ts
public tokenData = {
name: '',
address_line1: '',
address_line2: '',
address_city: '',
address_state: '',
address_zip: undefined,
address_country: ''
};
public submitForm = () => {
this.stripe.createToken(this.card, this.tokenData).then(res => {
if(res.error){
console.log(res.error.message);
}
else {
this.stripeTokenHandler(res.token).subscribe();
console.log(res.token);
}
});
};
public stripeTokenHandler(t){
return this.http.post(`${this.apiUrl}/charge`, t);
};
but when I submit the form the token gets logged to the console with the tokenData parameters empty, which means that the inputs aren't getting binding properly to tokenData. How can this be done?

You are not binding to the properties of the tokenData, add tokenData to all your bindings like [(ngModel)]="tokenData.address_line1"
<input type="text" [(ngModel)]="tokenData.name" placeholder="name" name="name">
<input type="text" [(ngModel)]="tokenData.address_line1" placeholder="adress line 1" name="address">
<input type="text" [(ngModel)]="tokenData.address_line2" placeholder="adress line 2" name="address">
<input type="text" [(ngModel)]="tokenData.address_city" placeholder="City" name="city">
<input type="text" [(ngModel)]="tokenData.address_state" placeholder="State" name="state">
<input type="text" [(ngModel)]="tokenData.address_country" placeholder="Country" name="country">

Related

getElementById return empty values so post empty values

I'm working with DOM and web API to POST some information about the company like name, worker's name.
But when I write something in the input DOM can't reach the value and return empty so I post an empty object.
That looks like :
adress: ""
companyName: ""
contactName: ""
contactTitle: ""
My form block:
<form>
<div class="form-group">
<label for="">Company Name</label>
<input
type="text"
class="form-control"
id="companyName"
placeholder="Company Name!"
/>
</div>
<div class="form-group">
<label for="">Contact Name</label>
<input
type="text"
class="form-control"
id="contactName"
placeholder="Contact Name!"
value=""
/>
</div>
<div class="form-group">
<label for="">Contact Title</label>
<input
type="text"
class="form-control"
id="contactTitle"
placeholder="Contact Title!"
/>
</div>
<div class="form-group">
<label for="">Country</label>
<input
type="text"
class="form-control"
id="inputCountry"
placeholder="Country!"
/>
</div>
</form>
And my JS code:
'use strict';
let inputCompanyName = document.getElementById('companyName');
let inputContactName = document.getElementById('contactName');
let inputContactTitle = document.getElementById('contactTitle');
let country = document.getElementById('inputCountry');
const btnSubmit = document.getElementById('submit');
let newCompany = {
companyName: inputCompanyName.value,
contactName: inputContactName.value,
contactTitle: inputContactTitle.value,
adress: country.value,
};
btnSubmit.addEventListener('click', e => {
e.preventDefault();
axios
.post('https://northwind.vercel.app/api/suppliers', newCompany)
.then(res => {
console.log('Response', res.data);
alert('Success!');
});
});
I tried innerHTML and innerText and form method but I cant solve this problem.
You're reading the values immediately upon loading the page, long before the user has had a chance to enter any values.
Instead, read the values in the click event:
btnSubmit.addEventListener('click', e => {
let newCompany = {
companyName: inputCompanyName.value,
contactName: inputContactName.value,
contactTitle: inputContactTitle.value,
adress: country.value,
};
// the rest of the click handler logic...
});

Can't push user-input to array in VueJS3

Hi and sorry for the Newbie-Question
I am trying to push a HTML-Input into an existing array on Button-click, but i cannot find my mistake.
Can anyone spot the mistake? The console.log(user) stays undefined and I don't know why the let newUser() I create does not get pushed into the array.
<template>
<div>
<form #submit.prevent="customSubmit">
<label>Name</label>
<input type="text" required name="name" id="name">
<label>E-mail:</label>
<input type="email" required name="email" id="email">
<label>Mobile Number</label>
<input type="number" required name="number" id="number">
</form>
<button type="submit" class=buttonSignup #click="customSubmit">Submit</button>
</div>
</template>
<script>
export default {
data() {
return{
user:[{
name: '',
email:'',
number:''
}]
};
},
methods: {
customSubmit(){
let newUser = {
name: document.getElementById('name').value,
email: document.getElementById('email').value,
number: document.getElementById('number').value
}
this.user.push(newUser)
console.log(this.user.value)
},
}
}
</script>
With Vue, you use v-model instead of directly accessing the DOM. For example, you can re-write your code by:
Change name=name to v-model=user.name
Use user and users. user collects one user's data and users collects all user input into an array. This is reflected in the modified customSubmit.
Reset user after each input.
There are more elegant ways to do this but this is the clearest and close enough to your original code.
<template>
<div>
<form #submit.prevent="customSubmit">
<label>Name</label>
<input type="text" required v-model="user.name" id="name">
<label>E-mail:</label>
<input type="email" required v-model="user.email" id="email">
<label>Mobile Number</label>
<input type="number" required v-model="user.number" id="number">
</form>
<button type="submit" class=buttonSignup #click="customSubmit">Submit</button>
<br/>
You typed:<br/>
name: {{user.name}}<br/>
email: {{user.email}}<br/>
number: {{user.number}}
</div>
</template>
<script>
export default {
data() {
return {
users: [],
user: {
name: '',
email: '',
number: ''
}
};
},
methods: {
customSubmit() {
// do some checking here
this.users.push(this.user)
this.user = {name:'', email:'', number:''};
console.log(this.users)
},
}
}
</script>

Using Jquery bootstrap validation to validate individual field in an array of fields along with sibling field

I have a form with form-groups each containing similar text fields and checkboxes which are sent as arrays when submitting the form as below:
<form method="POST" action="http://localhost/save-form" id="formAddUser">
<div class="form-group">
<input type="text" class="name" name="username[]" />
<input type="text" class="phone" name="phone[]" />
<input type="text" class="country" name="country[]" />
<input type="checkbox" class="isMobile" name="isMobile[]" />
</div>
<div class="form-group">
<input type="text" class="name" name="username[]" />
<input type="text" class="phone" name="phone[]" />
<input type="text" class="country" name="country[]" />
<input type="checkbox" class="isMobile" name="isMobile[]" />
</div>
<div class="form-group">
<input type="text" class="name" name="username[]" />
<input type="text" class="phone" name="phone[]" />
<input type="text" class="country" name="country[]" />
<input type="checkbox" class="isMobile" name="isMobile[]" />
</div>
</form>
After every time someone enters their phone, I want to do a remote validation but I would like to send isMobile field along with the request. Currently I am able to send the phone field for validation but couldn't send the corresponding mobile field along with it in the data attribute. Here is my code
$('#frmAddUser').bootstrapValidator({
fields: {
'phone[]': {
trigger: 'blur',
validators: {
notEmpty: {
message: ' '
},
remote: {
message: 'Phone does not exist',
url: 'http://localhost/verify-phone',
data: function () {
// leaving this empty just sends the phone. How do I send isMobile parameter along with this?
}
},
callback: {
callback: function () {
}
}
}
}
}
})
Edit: The following worked.
remote: {
message: 'Phone does not exist',
url: 'http://localhost/verify-phone',
data: function () {
var isMobile = validator.getFieldElements('isMobile[]').val()
}
},
As suggested by #Sumesh, using validator.getFieldElements('isMobile[]').val() worked
remote: {
message: 'Phone does not exist',
url: 'http://localhost/verify-phone',
data: function () {
var isMobile = validator.getFieldElements('isMobile[]').val()
}
}

Use class object as parameter in function to add to array

I would like to do a simple base where I can add memebers to array. I change a "Tour of Heroes" from Angular tutorial (link). What I want to do is instead of passing name (string) to function I would like to give a whole class object (User). I use form where user is typing his name and surname (and city if he want). I have no idea how to get from input to function this whole object, instead of list of string parameters. Here is my code:
form.html:
<div class="form-group">
<label for="Name">Name</label>
<input type="text" class="form-control" id="Name" required name="nameField" [(ngModel)]="ngModel" #nameField="ngModel" >
<div [hidden]="nameField.valid || nameField.pristine" class="alert alert-danger">Name is required</div>
</div>
<div class="form-group">
<label for="surname">surname</label>
<input type="text" class="form-control" id="surname" required name="surnameField" ngModel #surnameField="ngModel">
<div [hidden]="surnameField.valid || surnameField.pristine" class="alert alert-danger">Surname is required</div>
</div>
<div class="form-group">
<label for="city">City</label>
<input type="text" class="form-control" id="city" name="city" ngModel #cityField="ngModel" >
</div>
<button type="submit" class="btn btn-success" [disabled]="!userForm.form.valid">Submit</button>
</form>
function on submit:
onSubmit(name: string, surname: string, city: string ): void{
name = name.trim();
surname = surname.trim();
city = city.trim();
this.myservice.create(name, surname, city)
.then(newUser => this.arrayUsers.push(newUser));
}
And function create inside myservice:
private headers = new Headers({'Content-Type': 'application/json'});
private heroesUrl = 'api/mainArray'; // URL to web api
create(name: string, surname: string, city?: string): Promise<User> {
return this.http
.post(this.heroesUrl, JSON.stringify({name: name, surname:surname, city:city}), {headers: this.headers})
.toPromise()
.then(res => res.json().data as User);
}
Declare the ngModel attribute to bind each input to the form :
For example :
<input type="text" class="form-control" id="name" ngModel required name="nameField" >
<input type="text" class="form-control" id="surname" ngModel required name="surnameField" >
<input type="text" class="form-control" id="city" ngModel required name="cityField" ngModel >
And in the form element, give a name to the form to be able to bind it in the component and add the form as parameter in the onSubmit() method :
<form #f="ngForm" (ngSubmit)="onSubmit(f)" >
Now you should be able to retrieve the user with the f.value property :
onSubmit(f: NgForm): void{
this.myservice.create(f.value)
.then(createdUser=> this.arrayUsers.push(createdUser));
}
More information here : https://angular.io/api/forms/NgModel

How to post additional data within the scope of angular-payments

I'm trying to build a donation form using angular-payments and sending the data to an Expressjs server.
Currently I'm having trouble getting my form to post data other than the data that angular-payments sends. How can a post data that's not part of the angular-payments scope using the same controller?
Here is my Angular script:
angular.module('donate', ['angularPayments'])
function DonateCtrl($scope, $http) {
$scope.handleStripe = function(status, response){
console.log('response', status, response);
if(response.error) {
console.log('error');
// there was an error. Fix it.
} else {
// got stripe token, now charge it or smt
console.log('no error');
var token = response.id;
console.log(token);
return $http.post('http://localhost:8181/api/payments', response)
}
}
};
And here's the HTML:
<form stripe-form="handleStripe" name="donateForm">
<h3>Credit Card Details</h3>
<label for="">Card number</label>
<input type="text" name="number" ng-model="number" payments-validate="card" payments-format="card" payments-type-model="type" ng-class="donateForm.number.$card.type" placeholder="4500 0000 0000 0000" />
<label for="">Expiry</label>
<input type="text" ng-model="expiry" payments-validate="expiry" payments-format="expiry" placeholder="01 / 99" />
<label for="">CVC</label>
<input type="text" ng-model="cvc" payments-validate="cvc" payments-format="cvc" payments-type-model="type" placeholder="123" />
<h3>Donor Details</h3>
<label for="name">Name on card </label>
<input type="text" name="name" ng-model="name" placeholder="John Smith">
<label for="address">Street Address</label>
<input type="text" name="address" ng-model="addressLine1" placeholder="123 Any Street" required/>
<input type="text" name="city" ng-model="addressCity" placeholder="Anytown" required />
<input type="text" name="province" ng-model="addressState" placeholder="Any Province" ng-required="addressCountry == 'Canada' || addressCountry == 'United States'" />
<select data-placeholder="Choose a Country" name="country" ng-model="addressCountry" required>
{% include 'includes/countryselect' %}
</select>
<input type="text" name="postcode" ng-model="addressZip" placeholder="A1B 2C3" ng-required="addressCountry == 'Canada' || addressCountry == 'United States'" />
<div ng-show="donateForm.addressLine1.$pristine && donateForm.addressLine1.$invalid || donateForm.addressCity.$pristine && donateForm.addressCity.$invalid || donateForm.addressState.$pristine && donateForm.addressState.$invalid || addressCountry.$pristine && addressCountry.$invalid || donateForm.addressZip.$pristine && donateForm.addressZip.$invalid" class="help-block">Enter your full home address.</div>
<label for="phone">Phone Number <small>(include country & area code)</small></label>
<input type="tel" name="phone" ng-model="phone" placeholder="+1 204-555-5555" required />
<div ng-show="donateForm.phone.$invalid && donateForm.phone.$pristine" class="help-block">Enter your phone number.</div>
<label for="email">Email Address</label>
<input type="email" name="email" ng-model="email" placeholder="johnsmith#email.com" required />
<div ng-show="donateForm.email.$invalid && donateForm.email.$pristine" class="help-block">Enter your email address.</div>
<button type="submit">Submit</button>
When you say post additional data, do you mean send data with the POST request?
This is how I do it as an example:
$http({
url: 'http://localhost:8181/api/payments',
method: 'POST',
data: {
key: value,
key2: value
}).success(function(data) {
// If successful
}).error(function(data) {
// If error
return data.message;
});

Categories