how to display api errors in javascript - javascript

I am working with stripe, using the code found on their page to create a new account. Everything works fine, however when someone inserts wrong data in a field and we press on submit nothing happens and I can see in the console:
{
"error": {
"message": "This value must be greater than 1900 (it currently is '1670').",
"param": "account[individual][dob][year]",
"type": "invalid_request_error"
}
this being the response of the api (I tried to enter 1670 in the date of birth).
how can I display this on the page for the user?
here is my html code for the page:
<form class="my-form" method="post" role="form">
{% csrf_token %}
<input type="hidden" name="token" id="token">
<label>
<span>First Name</span>
<input class="inp-first-name" name="first_name" required>
</label>
<label>
<span>Last Name</span>
<input class="inp-last-name" name="last_name" required>
</label>
<label>
<span>dob year</span>
<input class="inp-dob-year" name="dob_year" required>
</label>
<label>
<span>dob month</span>
<input class="inp-dob-month" name="dob_month" required>
</label>
<label>
<span>dob day</span>
<input class="inp-dob-day" name="dob_day" required>
</label>
<fieldset>
<legend>Address</legend>
<label>
<span>Street Address Line 1</span>
<input class="inp-street-address1" name="street_address1" required>
</label>
<label>
<span>Street Address Line 2</span>
<input class="inp-street-address2" name="street_address2">
</label>
<label>
<span>City</span>
<input class="inp-city" name="city" required>
</label>
<label>
<span>State</span>
<input class="inp-state" name="state" required>
</label>
<label>
<span>Postal Code</span>
<input class="inp-zip" name="zip" required>
</label>
{{ form }}
</fieldset>
<button type="submit">Submit</button>
</form>
</table>
{% endblock %}
{% block body_scripts %}
<script>
const stripe = Stripekey
const myForm = document.querySelector('.my-form');
myForm.addEventListener('submit', handleForm);
async function handleForm(event) {
event.preventDefault();
const result = await stripe.createToken('account', {
legal_entity: {
type:'individual',
first_name: document.querySelector('.inp-first-name').value,
last_name: document.querySelector('.inp-last-name').value,
dob:{
year: parseInt(document.querySelector('.inp-dob-year').value),
month: parseInt(document.querySelector('.inp-dob-month').value),
day: parseInt(document.querySelector('.inp-dob-day').value),
},
address: {
line1: document.querySelector('.inp-street-address1').value,
line2: document.querySelector('.inp-street-address2').value,
city: document.querySelector('.inp-city').value,
state: document.querySelector('.inp-state').value,
postal_code: document.querySelector('.inp-zip').value,
},
},
tos_shown_and_accepted: true,
});
if (result.token) {
document.querySelector('#token').value = result.token.id;
myForm.submit();
}
}
</script>
I am building a website with python, so my knowledge with javascript is limited. Any help would be appreciated.

You can achieve this by adding a new HTML element to contain error messages and setting the innerText to the error message.
I added a div with an id of stripe-errors
if (result.token) {
document.querySelector('#token').value = result.token.id;
myForm.submit();
} else if (result.error) {
let stripeErrors = document.getElementById('stripe-errors');
stripeErrors.innerText = result.error.message;
}
The limitation of that is that you only have one place to display the error messages and the error messages don't explicitly say what field they're referencing, although within context it is probably clear enough. To be crystal clear you could use the error.param to map account[individual][dob][year] to the .inp-dob-year input field or to another element to display the error message.
This would look something like:
if (result.token) {
document.querySelector('#token').value = result.token.id;
myForm.submit();
} else if (result.error) {
// create an object as a map from the error.param to the elements that should be used to display error messages
const errorTypeFieldMap = {
'account[individual][dob][year]': '.inp-dob-year-error'
}
let errorElementSelector = errorTypeFieldMap[result.error.param];
if (errorElementSelector !== undefined) {
let errorElement = document.querySelector(errorElementSelector);
errorElement.innerText = result.error.message;
} else {
// display a generic error?
}
}

You should get the error(create a variable for the error json and parse it for the exact response you want) in the same function as you did the request and then get the element of the element you want to show the error message and asign the value of the response you want to show. You could use some
var x = document.getElementById(variable);
x.value = variable with the error;
}

Related

JS authentication for HTML page

I want to add a basic name and email validation JS script to an HTML page, so when submit is pressed it will check multiple fields and throw errors if any are filled incorrectly. Unfortunately, when submit is pressed the page just reloads with fields empty and no error is thrown on the HTML page.
I am still learning JS.
Here is my JS snippet to check for name and email:
//Check if name is anything other than letters or spaces. If it isn't throw error.
function validateForm() {
var validEntry = /[a-zA-Z ]/;
var x = document.forms["clientinfo"]["txtFullName"].value;
if (x.value.match(!validEntry)) {
alert("Invalid name. Please try again.");
document.clientinfo.txtFullName.focus();
return false;
}
// Check if email is in proper format - words#words.com. If it isn't throw error.
var y = document.forms["clientinfo"]["txtEmail"].value;
var validEmail = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})/
if (y.value.match(validEmail)) {
return true
} else {
alert("Invalid email. Please try again.")
document.clientinfo.txtEmail.focus();
return false;
}
}
<div id="inputArea">
<form name="clientinfo" onsubmit="return validateForm()" method="post">
Name:
<input class="Inputinfo" type="text" name="txtFullName" placeholder="John Stewart" required>
<br> Email:
<input class="Inputinfo" type="text" name="txtEmail" placeholder="john#example.com" required>
<br> Phone:
<input class="Inputinfo" type="tel" name="phone" placeholder="XXX-XXX-XXXX" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" required>
<br> Description:
<br>
<textarea class="Inputinfo" id="txtDescription" name="description" rows="8" cols="50" placeholder="Please enter any additional client information here."></textarea>
<br>
<input type="submit" value="Enter" id="enterbutton">
</form>
</div>
How can I fix this problem?
!validEntry is false, so you're testing x.value.match(false) in your first if statement. What you want is if (!x.value.match(validEntry)) and you have to change the regexp to match the entire input string (it currently looks for a match of the valid characters anywhere in the input.
x.value and y.value should just be x and y. You already used .value when you assigned the variables, so they contain strings, not the input elements.
To make it easier to keep adding more validations, don't do return true when the email is valid. Put that at the end of the function, and just do return false in each of the invalid cases.
//Check if name is anything other than letters or spaces. If it isn't throw error.
function validateForm() {
var validEntry = /^[a-zA-Z ]+$/;
var x = document.forms["clientinfo"]["txtFullName"].value;
if (!x.match(validEntry)) {
alert("Invalid name. Please try again.");
document.clientinfo.txtFullName.focus();
return false;
}
// Check if email is in proper format - words#words.com. If it isn't throw error.
var y = document.forms["clientinfo"]["txtEmail"].value;
var validEmail = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})$/
if (!y.match(validEmail)) {
alert("Invalid email. Please try again.")
document.clientinfo.txtEmail.focus();
return false;
}
return true;
}
<div id="inputArea">
<form name="clientinfo" onsubmit=" validateForm(); return false" method="post">
Name:
<input class="Inputinfo" type="text" name="txtFullName" placeholder="John Stewart" required>
<br> Email:
<input class="Inputinfo" type="text" name="txtEmail" placeholder="john#example.com" required>
<br> Phone:
<input class="Inputinfo" type="tel" name="phone" placeholder="XXX-XXX-XXXX" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" required>
<br> Description:
<br>
<textarea class="Inputinfo" id="txtDescription" name="description" rows="8" cols="50" placeholder="Please enter any additional client information here."></textarea>
<br>
<input type="submit" value="Enter" id="enterbutton">
</form>
</div>

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.

Trouble creating Stripe Token: 402 (Payment Required) error

Good day everyone,
Below is the error code that is thrown in console:
(index):3 POST https://api.stripe.com/v1/tokens 402 (Payment Required)
(index):3 POST https://api.stripe.com/v1/tokens 402 (Payment Required)c # (index):3e # (index):3a # (index):3Stripe.isDoubleLoaded.Stripe.xhr # (index):3Stripe.a._rawRequest # (index):2Stripe.a.request # (index):2Stripe.token.a.create # (index):2Stripe.card.b.createToken # (index):2Stripe.a._channelListener # (index):2incoming # (index):2f # (index):2
Below is the javascript code
// Generate the user token
$(function() {
// Once the user has submited the form
$(".submit").click(function(e) {
// Prevent the form from submiting by default
e.preventDefault();
// Ensure that checkbox is checked
if($('#checkbox').is(":checked")) {
// Prevent the form from submiting by default
var $form = $('#payment-form');
// Request a token from Stripe:
Stripe.card.createToken($form, stripeResponseHandler);
// Prevent the form from being submitted:
return false;
}
else {
// Display an error message to the user by writting directly into the header error tag
document.getElementById('checkboxError').innerHTML = "You must kindly accept the terms and conditions to continue.";
}
});
// Ensure that checkbox is checked
if($('#checkbox').is(":checked")) {
var appendedStripeToken = false;
function stripeResponseHandler(status, response) {
// Grab the form:
var $form = $('#payment-form');
if (response.error) { // Problem!
// Scroll to the billing section
$("#billingError").scrollTop();
// Show the errors on the form:
$form.find('.payment-errors').text(response.error.message);
$form.find('.submit').prop('disabled', false); // Re-enable submission
} else { // Token was created!
// Get the token ID:
var token = response.id;
handleCall(token);
}
// What to do after the token has been generated.
function handleCall(token) {
var $form = $('#payment-form');
if (!appendedStripeToken) {
// Insert the token into the form so it gets submitted to the server
appendedStripeToken = true;
phpCall();
}
}
// Post the package name, the token, and the user name information to the billing.php page
function phpCall() {
if( appendedStripeToken === true ){
$.ajax({
type: "POST",
data: {run: true, packageName: $('#packageName').val(), token: token, userName: $('#userName').val(),customerName: $('#customerName').val() },
url: '/app/functions/billing.php',
success: function (response) {//response is value returned from php (for your example it's "bye bye"
$('#payment-form').prop('disabled', true); // TODO: give your html-submit-input-tag an "id" attribute
window.location = response;
}
});
}
}
}
}
});
Below is the HTML code
<!-- Package name to be submitted to server -->
<input type="hidden" id="packageName" value="{{ packageName|capitalize }}">
<!-- Username to be submitted to server -->
<input type="hidden" id="userName" value="{{ userName }}">
<input type="hidden" id="customerName" value="{{ customerName }}">
<div class="form-row">
<label for="cardHolder">Cardholder Name</label><br>
<input type="text" id="cardHolder" size="20" data-stripe="name">
</label>
</div>
<br><br>
<div class="form-row">
<label for="cardNumber">Card Number </label><br>
<input type="text" id="cardNumber" size="20" data-stripe="number">
</label>
</div>
<br>
<img src="/public/images/credit-card/visa.png" class="card-visa">
<img src="/public/images/credit-card/mastercard.png" class="card-mastercard">
<img src="/public/images/credit-card/american-express.png" class="card-aexpress">
<br>
<div class="form-row">
<label for="cardExpiration"> Expiration (MM/YY)</label><br>
<input class="expirationNumber" type="text" size="2" id="cardExpiration" data-stripe="exp_month">
</label>
<span> / </span>
<input class="expirationNumber" type="text" size="2" data-stripe="exp_year">
</div>
<br><br>
<div class="form-row">
<label for="cardCVC">CVC</label><br>
<input type="text" id="cardCVC" size="4" data-stripe="cvc">
</label>
</div>
</div>
</div>
<input type="checkbox" id="checkbox">
<label for="checkbox">By purchasing this package you are agreeing to our Terms & Conditions</label><br><br>
<h4 id="checkboxError"></h4>
<button type="submit" class="submit btn-tangerine">Submit Payment</button>
</form>
Any help would be greatly appreciated!
I thnk that the main error lies in the following line:
Stripe.card.createToken($form, stripeResponseHandler);
What is suppose to happen is really simple. Token gets created when all proper information are given, and then the token along with other information are posted via ajax to the server where a PHP code will create the charge using these information.
I was facing same issue when I add test API KEYS for payment, then site was working fine and when I add live key then site shows same error on console.
But problem was, I was testing live key with test credit card number. May be you were doing same mistake
And sorry for bad English.

Trouble with Ajax/json and spring mvc

--edit--
What is happening is I can see with console/sout items that I am getting the object from the DB, and currentyly I am getting a 500 internal server error, every fix I have tried one error goes away (400 has been very popular) and then I get another, i fix it then I get another.
I am getting the data, but it the call keeps failing and I can't do anything with the information, I am seeing that data, but I can't figure out how to catch it properly.
What I am trying to do is search for a customer, if that customer exists populate that information in the next page form, if not just insert the search criteria into the corresponding fields in the next page form.
Here is javascript, I can't figure out the load function because it doesn't seem to work right (not sure how to catch the data correctly it seems).
$('#search-customer').click(function (event) {
var testdata = document.getElementById('searchCustomerForm');
// var isvalid = checkForm(form);
// if (isvalid === false) {
// event.preventDefault();
// alert('is valid===false');
// } else {
alert('hit search customer ajaxcall');
$.ajax({
type: 'GET',
url: 'customerLookup/?firstName=' + $('#search_first_Name').val() + '&lastName=' + $('#search_last_Name').val() + '&compId=' + companyId,
data: JSON.stringify({
firstName: $('#search-first_name').val(),
lastName: $('#search-last_name').val(),
// dob: $('#search_birthdate').val(),
// license: $('#search_license_number').val()
// dob: $('#search_birthdate').val(),
compId: $('#search_companyId').val(companyId)
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
'dataType': 'json'
}).done(function (data, status) {
if (data !== null) {
window.location = "/app/ticketStepOneTwoAddCustomer";
loadCustomerInputForm(data, status);
alert('customer found, moving to confirm');
}
else if (data === null) {
window.location = "/app/ticketStepOneTwoAddCustomer";
addSearchInfoToInputCustomerForm();
alert('no customer of that name found, moving to add customer');
}
}).fail(function () {
alert('not a success');
// window.location = "/app/ticketStepOneTwoAddCustomer";
});
});
function loadinputcustomerform(data, status) {
alert('hit loadinputcustomerform function');
console.log(cust.customer.getCustomerFirstName());
console.log(data.customer.getCustomerMiddleName());
console.log(customer.getCustomerLastName());
Here is the Controller
#RequestMapping(value = {"/customerLookup"}, method = RequestMethod.GET)
#ResponseBody
public Customer getCustomerByCriteria(
#RequestParam(value = "compId", required = false) int compId,
#RequestParam(value = "firstName", required = false) String fName,
#RequestParam(value = "lastName", required = false) String lName) {
System.out.println("here: " + compId + " -- " + fName);
Customer cust = customerService.searchCustomer(fName, lName, compId);
//System.out.println(cust.getCustomerLicense());
return cust;
}
On the java side the customer is just an object, in the DB the companyID is the FK, everything requires the compID, I was thinking They should have made a customer hashmap or list but not my area and it is what I have to work with.
here is the html
<form id="inputCustomerForm">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="input_first_Name" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="First Name">
</div>
<div class="form-group">
<label for="middleName">Middle Name</label>
<input type="text" class="form-control" id="input_middle_Name" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="Middle Name">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="input_last_Name" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="Last Name">
</div>
<div class="form-group">
<label for="dob">D.O.B. YYYYMMDD</label>
<input type="text" class="form-control" id="input_birthdate" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="YYYYMMDD">
</div>
<div class="form-group">
<label for="addressone">Address</label>
<input type="text" class="form-control" id="input_addressone" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="123 street">
</div>
<div class="form-group">
<label for="addresstwo">Address</label>
<input type="text" class="form-control" id="input_addresstwo" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="po 1111">
</div>
<div class="form-group">
<label for="city">City</label>
<input type="text" class="form-control" id="input_city" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="Columbus">
</div>
<div class="form-group">
<label for="state">State</label>
<input type="text" class="form-control" id="input_state" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="OH">
</div>
<div class="form-group">
<label for="zip">ZipCode</label>
<input type="text" class="form-control" id="input_zip" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="43026">
</div>
<div class="form-group">
<label for="licenseNumber">License Number</label>
<input type="text" class="form-control" id="input_license_number" style="text-transform:uppercase;" onkeyup="this.value = this.value.toUpperCase()" placeholder="License Number">
</div>
<div class="form-group">
<label for="licenseInputFile">File input</label>
<input type="file" id="licensePhoto">
<p class="help-block">License Photo</p>
</div>
<div class="form-group">
<label for="customerPhotoInputFile">File input</label>
<input type="file" id="customerPhoto">
<p class="help-block">Customer Photo</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
</div>
<button type="reset" class="btn btn-default">Clear</button>
<button type="submit" id="input-customer" class="btn btn-default" >Submit</button>
</form>
here is the response
HTTP Status 500 - Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.REMOVED.DTO.Customer["company"]->com.REMOVED.DTO.Company_$$_jvstf68_6["handler"]); nested exception is org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.REMOVED.DTO.Customer["company"]->com.REMOVED.DTO.Company_$$_jvstf68_6["handler"])
type Exception report
message Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.REMOVED.DTO.Customer["company"]->com.REMOVED.DTO.Company_$$_jvstf68_6["handler"]); nested exception is org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.REMOVED.DTO.Customer["company"]->com.REMOVED.DTO.Company_$$_jvstf68_6["handler"])
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.REMOVED.DTO.Customer["company"]->com.REMOVED.DTO.Company_$$_jvstf68_6["handler"]); nested exception is org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.REMOVED.DTO.Customer["company"]->com.REMOVED.DTO.Company_$$_jvstf68_6["handler"])
org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:212)
org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:207)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:148)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:193)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
root cause
org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.REMOVED.DTO.Customer["company"]->com.REMOVED.DTO.Company_$$_jvstf68_6["handler"])
org.codehaus.jackson.map.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:52)
org.codehaus.jackson.map.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:25)
org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:1613)
org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:209)
org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:207)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:148)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:193)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
note The full stack trace of the root cause is available in the Apache Tomcat/8.0.15 logs.
I was thinking that the customer properties being private was an issue but with public getters and setters i thought it would still work.

How do you edit and add new fields to the Current User in Meteor?

In Meteor the current user simply has a "name" field. I want to add a first_name and last_name under profile.
My user_edit.html form:
<template name="userEdit">
<div id="login-wrapper">
<form id="login-form" action="action" class="form login-form">
<div class="control-group">
<div class="controls">
<input name="first_name" type="text" value="" placeholder="First Name"/>
</div>
</div>
<div class="control-group">
<div class="controls">
<input name="last_name" type="text" value="" placeholder="Last Name"/>
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="submit" value="Submit" id="submit-website-button" class="btn btn-primary"/>
</div>
</div>
</form>
</div>
</template>
I have a form for editing the current user:
I'm not too sure how to update the current user in user_edit.js and add additional fields for first and last name. The code below doesn't work.
Template.userEdit.events({
'submit form': function(e) {
e.preventDefault();
var currentUserId = this._id;
var userProperties = {
first_name: $(e.target).find('[name=first_name]').val(),
last_name: $(e.target).find('[name=last_name]').val()
}
User.update(currentUserId, {$set: userProperties}, function(error) {
if (error) {
// display the error to the user
alert(error.reason);
} else {
Router.go('userPage', {_id: currentUserId});
}
});
}
});
EDIT
Here is the working version of my JS file after applying the answer:
Template.userEdit.events({
'submit form': function(e) {
e.preventDefault();
Meteor.users.update( Meteor.userId(),
{
$set: {
'profile.first_name': $(e.target).find('[name=first_name]').val(),
'profile.last_name': $(e.target).find('[name=last_name]').val(),
'profile.cell_phone': $(e.target).find('[name=cell_phone]').val(),
'profile.email': $(e.target).find('[name=email]').val(),
'profile.business_name': $(e.target).find('[name=business_name]').val(),
'profile.website': $(e.target).find('[name=website]').val()
}
},
function(error) {
if (error) {
// display the error to the user
alert(error.reason);
} else {
Router.go('userPage', {_id: Meteor.userId() });
}
}
);
}
});
A couple of things. I haven't used the past couple of updates of Meteor so maybe 'User' has been added as a cursor to update the current user but from my experience this is how you would update the current user:
Meteor.users.update( Meteor.userId(), { $set: { 'profile.first_name': "example" } } );
Also note how I had to specify 'profile.first_name', in your snippet you would be trying to set first_name and last_name in the base of the user object when users are only allowed to edit the profile section client side. Lastly I'm not sure what 'this' is in the context of your Template so I would set currentUserId = Meteor.userId(), a convenient way to get the current user's id.

Categories

Resources