I learn Angular from Tour of heroes and I develop my own project.
I have a backend written in Java witch returns status 500 if operation is failed.
The response if operation is failed looks like below:
{"timestamp":1497911402842,"status":500,"error":"Internal Server Error","exception":"javax.validation.ConstraintViolationException","message":"Content of message"}
My service:
getProducts(): Promise<Product[]> {
return this.http.get(this.productsUrl)
.toPromise()
.then(response => response.json() as Product[])
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occured ', error);
return Promise.reject(error.message);
}
My form component:
export class ProductFormComponent {
constructor(private productService: ProductService) {}
model: Product = new Product(
1,
'Name of product'
);
result: Product= new Product(
null,
null
);
submitted = false;
onSubmit(): void {
this.submitted = true;
this.productService.create(this.model)
.then(response => this.result = response);
}
clearForm(): void {
this.model = new Product(
null,
''
);
}
}
And form looks like below:
<div class="container">
<div [hidden]="submitted" class="container">
<h1>Product form</h1>
<form (ngSubmit)="onSubmit()" #productForm="ngForm">
<div class="form-group">
<label for="productId">Product id:</label>
<input type="text" class="form-control" id="productId" required [(ngModel)]="model.productId" name="productId" #productId="ngModel">
</div>
<div class="form-group">
<label for="productName">Product name:</label>
<input type="text" class="form-control" id="productName" required [(ngModel)]="model.productName" name="productName" #productName="ngModel">
<div [hidden]="productName.valid" class="alert alert-danger">
Product name is required
</div>
</div>
<button type="button" class="btn btn-default" (click)="clearForm(); productForm.reset()">Clear form</button>
<button type="submit" class="btn btn-success" [disabled]="!productForm.form.valid">Submit</button>
</form>
</div>
<div [hidden]="!submitted">
<h2>Submitted product:</h2>
<div class="row">
<div class="col-xs-3">Product name:</div>
<div class="col-xs-9 pull left">{{ result.productName }}</div>
</div>
<div class="row">
<div class="col-xs-3">Product id:</div>
<div class="col-xs-9 pull left">{{ result.productId }}</div>
</div>
<br/>
<button class="btn btn-primary" (click)="submitted=false">Edit</button>
</div>
</div>
And the problem is that when I submit incorrect value I get status 500 in response and I would like to print result as null values or print some message if result is null but in result I get values from form. And I don't know how to catch the bad status from response. Then I could set adequate statement or message.
Make the following adjustment in your handleError function:
return Promise.reject(error);
Then add following code in onSubmit() function:
onSubmit(): void {
this.submitted = true;
this.productService.create(this.model)
.then(response => { this.result = response },
error => {
if(error.status == 500){
alert(JSON.stringify(error));
this.result = null;
//you can add more steps here
}
});
}
Related
So for form actions, I made a class to make things cleaner, but there's a problem. Whenever any errors/success messages are set in the class, Svelte does not automatically rerender the changes.
Frontend:
<script>
import Form from '#/periphs/form'
let changePasswordForm = new Form()
changePasswordForm.form.values = {
newPassword: null,
currentPassword: null
}
changePasswordForm.params.endpoint = route('api.user.settings.security.change-password')
const changePassword = () => {
changePasswordForm.execute()
}
</script>
<div class="block">
<div class="is-size-6 has-text-weight-light">Change Password</div>
<div class="field help has-text-grey-light">
1. Use special characters. (!##$%^&*)
<br>2. Do not reuse passwords.
<br>3. Do not use passwords that can be guessed. (Birthdays, names, numbers, etc).
</div>
<fieldset disabled={ changePasswordForm.form.processing }>
<div class="field">
<div class="control">
<label for="" class="label is-small">New Password</label>
<input bind:value={ changePasswordForm.form.values.newPassword } class:is-danger={ changePasswordForm.form.errors.newPassword } type="password" class="input is-small" placeholder="New Password">
</div>
{#if changePasswordForm.form.errors.newPassword}
<div class="help is-danger">{ changePasswordForm.form.errors.newPassword }</div>
{/if}
</div>
<div class="field">
<div class="control">
<label for="" class="label is-small">Current Password</label>
<input bind:value={ changePasswordForm.form.values.currentPassword } class:is-danger={ changePasswordForm.form.errors.currentPassword } type="password" class="input is-small" placeholder="Current Password Password">
</div>
{#if changePasswordForm.form.errors.currentPassword}
<div class="help is-danger">{ changePasswordForm.form.errors.currentPassword }</div>
{/if}
</div>
<div class="field">
<button on:click={ () => changePassword() } class="button is-primary is-small">Change Password</button>
{#if changePasswordForm.form.success.message}
<div class="help is-success">{ changePasswordForm.success.message }</div>
{/if}
{#if changePasswordForm.form.errors._flood}
<div class="help is-danger">{ changePasswordForm.errors._flood }</div>
{/if}
</div>
</fieldset>
</div>
Form.js:
'use strict'
import axios from "axios"
export default class Form {
constructor() {
this.form = {
processing: false,
success: {},
errors: {},
values: {}
}
this.params = {
method: 'POST',
endpoint: null,
}
}
getErrors() {
return this.form.errors
}
execute() {
/*
Before form submission, reset all errors/successes
*/
this.form.processing = true
this.form.success = {}
this.form.errors = {}
if (this.params.method == 'POST') {
axios.post(this.params.endpoint).then(r => {
/*
Handle success
*/
this.form.errors = {}
this.form.success = r.data
}).catch(e => {
/*
422
Form errors (Validation)
*/
if (e.response.status == 422) {
this.form.errors = e.response.data.errors
}
/*
429
Request timeout (Flood)
*/
if (e.response.status == 429) {
this.form.errors = { ...this.form.errors, ...{ '_flood': e.response.data.message } }
}
console.log(this.form.errors) // SHOWS ERRORS AS ITS SUPPOSED TO, BUT THIS IS NOT REPRODUCED ON THE FRONTEND
}).finally(() => {
this.form.processing = false
})
}
}
}
Whenever there is an error/success, it should show those changes on my front end, but that is not the case. Any one got any idea on how to fix this?
Reactivity only works for code within components, outside you need to use stores or events to signal changes.
Handlebar templete is used as views and nodejs is used in backend. i want to save detail in backend on submit of second form.
{{> alertmessage}}
Website Name*
Check Availability
</form>
<form class="form-horizontal" action="/institute/create" method="POST">
<div class="form-group">
<label for="fullname" class="col-sm-2 control-label">Institute Name*</label>
<div class="col-sm-10">
<div class="form-line">
<input type="text" class="form-control" id="institute_name" name="institute_name"
placeholder="institute_name" value="{{institute.institute_name}}" required>
</div>
</div>
</div>
<div class="form-group">
div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Create</button>
<a class="btn btn-warning" href="/adminusers">Go to adminusers</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
instituteRouter.post('/checkSubdomainAvailability', async (req, res) => {
let { success, error, validationError } = req.session;
institute_subdomain = req.body.institute_subdomain;
const response = await institute.findOne({ institute_subdomain: institute_subdomain }).exec();
if (response === null) {
console.log('response.institute_subdomain');
req.session.success = 'Subdomain is available.'
req.session.error = null;
return res.redirect("/institute/create");
}
else {
req.session.error = 'Subdomain is taken. Please try again.'
req.session.success = null;
return res.redirect("back");
}
})
instituteRouter.post('/create', async (req, res) => {
let { success, error, validationError } = req.session;
check('owner', 'Please select owner.').notEmpty();
let institute_subdomain = req.body.institute_subdomain;
let { institute_name } = req.body;
let pageToCreate = {
institute_name, institute_subdomain
};
let createdPage = await institute.create(pageToCreate);
if (createdPage) {
req.session.success = 'Institute created successfully.'
return res.redirect('/institute');
}
else {
req.session.error = 'Error occurred in creating a new page';
return res.redirect('/institute');
}
})
I have defined isError as false in data, however once there is an error from laravel i get the 422 error. I would like to then define isError as true but when i do it i get an error from the console saying that iserror is undefined even though it has been defined. What is the problem?
The error is as per below:
app.js:1925 Uncaught (in promise) ReferenceError: isError is not defined
Thanks
<template>
<div class="contact-section">
<div class="container">
<div class="section-content row">
<div class="contact-text col-lg-6">
<div class="text-box">
<h1 class="subtitle text-white">Contact</h1>
<h2 class="text-white"> Have You Any Project? <br> Please Drop a Message </h2>
<p class="text-white"> Get in touch and let me know how i can help. Fill out the form and i’ll be in touch as soon as possible. </p>
</div>
<ul class="contact-info">
<li>
<img src="assets/images/icons/email.png" alt="Email">
<div>
<strong>Email:</strong>
<ul>
<li>info#nafie.com</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="col-lg-6">
<form class="contact-form form-styled" #submit.prevent="send">
<div class="group">
<label>Name</label>
<div class="control has-prefix-icon">
<input type="text" name="name" placeholder="e.g. John Doe" minlength="3" v-model="form.name">
</div>
</div>
<div class="group">
<label>Email</label>
<div class="control has-prefix-icon">
<input class="ltr-dir" type="email" name="email" placeholder="e.g. john.doe#gmail.com" v-model="form.email">
</div>
</div>
<div class="group">
<label>Message</label>
<div class="control has-prefix-icon">
<textarea name="message" placeholder="Write message..." v-model="form.message"></textarea>
</div>
</div>
<div class="group">
<p v-if="isError" class="error large">All fields are required</p>
<div class="control"><button class="submit-btn btn btn-dark" type="submit">Send</button></div>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data: function() {
return {
form: {
email: '',
message: '',
name: ''
},
errors: {},
isError: false
}
},
methods: {
send: function() {
// Reset is error
this.isError = false;
axios.post("/send", this.form)
.then(function (response) {
// Reset form on success
this.form.name = '';
this.form.email = '';
this.form.message = '';
console.log(response);
})
.catch(function (error) {
// Says here undefined?
this.isError = true;
console.log(error);
console.log(error.response.data.errors);
});
}
}
}
</script>
send: function()
{
// Reset is error
this.isError = false;
let self = this;
axios.post("/send", this.form).then(function(response)
{
// Reset form on success
self.form.name = '';
self.form.email = '';
self.form.message = '';
console.log(response);
}).catch(function(error)
{
// Says here undefined?
self.isError = true;
console.log(error);
console.log(error.response.data.errors);
});
}
I'm creating login validation in Vue.js but the error message is not displaying and it gives me the error:
Property or method "error" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Any help?
Template:
<template>
<div class="container" width="900">
<div class="row justify-content-center" style="margin-top: 10px;">
<div class="col-5">
<div v-if="error" class="alert alert-danger" role="alert">
{{error}}
</div>
<div class="card" >
<div class="card-text">
<div class="form-group" #keyup.enter="logItIn">
<input class="form-control"
v-model="login.email"
label="Email"
placeholder="Email Address"
required
> <br>
<input class="form-control"
v-model="login.password"
label="Password"
type="password"
placeholder="Password"
required>
</div>
</div>
<button type="button" class="btn btn-secondary" #click='logItIn'>Login</button>
</div>
</div>
</div>
</div>
</template>
Script:
import axios from 'axios'
export default {
data() {
return {
login: {
email:"",
password:"",
error: ""
}
}
},
methods: {
async logItIn() {
try {
axios.post('https://odevin-api.herokuapp.com/login',this.login)
.then(response => {
console.log(response)
let newToken=response.data.response.token;
window.token=newToken;
let user=response.data.response.user; //response
localStorage.setItem('token',newToken);
localStorage.setItem('user',JSON.stringify(user));
window.axios.defaults.params={api_token:newToken}
// Event.$emit('login',user);
this.$router.push('/');
});
} catch(e) {
this.error = 'invalid user name or password';
}
}
}
}
you referenced {{ error }} in your template but in your data object, error is a property of login object. so vue can't find it properly.
either change the usage in your template to {{ login.error }} or define it in your data object like this:
data() {
return {
error: '',
login: {
email: '',
password: '',
},
}
}
I need to display error or success messages after populate a form in the view, and if the action method of a controller catch an exception or not then show a message that the registration on a form was successful or not.
This is my HTML code of the form:
#using (Html.BeginForm("GetSolictudMarca", "Gestion", FormMethod.Post, new { #id = "Frm-login", role = "form", #class = "form-horizontal" }))
{
<div class="panel panel-default" style="width:80%;margin:0 auto;">
<div class="panel-heading"></div>
<div class="panel-body">
<div class="row">
<div class="col-lg-6">
<br />
<div class="form-group-sm">
<div class="col-lg-10">
<p> <strong>Nº Expediente:</strong></p>
<input class="form-control" id="expedienteNro" name="expedienteNro" type="number" placeholder="Nº Expediente" required autocomplete="off" onkeypress="return pulsarExpediente(event)">
</div>
</div>
</div>
</div>
<br />
<div class="row ">
<div class="col-lg-6">
<div class="form-group-sm">
<div class="col-lg-10">
<p><strong>Fecha Solicitud:</strong></p>
#(Html.Kendo().DateTimePicker()
.Name("fechaSolicitud")
.Value(DateTime.Now)
.HtmlAttributes(new { style = "width:100%;", required = "required" })
)
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group-sm">
<div class="col-lg-10">
<p><strong>Fecha Estado:</strong></p>
#(Html.Kendo().DateTimePicker()
.Name("fechaEstado")
.Value(DateTime.Now)
.HtmlAttributes(new { style = "width:100%;", required = "required" })
)
</div>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-6">
<div class="form-group-sm">
<div class="col-lg-10">
<p><strong>Pais:</strong></p>
#(Html.Kendo().ComboBox()
.Name("pais2")
.DataTextField("PaisDescripcion")
.DataValueField("PaisCodigo")
.HtmlAttributes(new { style = "width:100%", required = "required" })
.Filter(FilterType.StartsWith)
.IgnoreCase(true)
.Placeholder("Seleccione un país...")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetPais", "Gestion");
});
})
)
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4" style="margin-left:30px; margin-top:30px; width:100%">
<button class="btn btn-success" type="submit" id="btnRegistrar">Registrar</button>
<button class="btn btn-success" type="reset">Cancelar</button>
</div>
</div>
<div class="row">
#*#Html.ValidationSummary("error")*#
<div class="alert ">
#Html.ValidationMessage("error", new { #id = "validationMessage" })
</div>
</div>
</div>
</div>
}
And this my controller:
public async Task<ActionResult> GetSolictudMarca(FormCollection frm)
{
string ExpedienteGeneral = Request.Form["expedienteNro"];
string fechaSolicitud = Request.Form["fechaSolicitud"];
string fechaEstado = Request.Form["fechaEstado"];
string pais = Request.Form["pais2"];
return await Task.Run(() =>
{
string sqlString = "select * from gmc_expediente where exp_codigo = :selectExpNro";
string queryRoles = "insert into gmc_expediente(EXP_CODIGO,\n" +
"EXP_FECHA_SOLICITUD,\n" +
"EXP_FECHA_ESTADO,\n" +
"EXP_PAIS)\n" +
"values(:ExpCodigo,\n" +
" :fechaSolicitud ,\n" +
" :fechaEstado,\n" +
" :pais)";
#region Conexion
string cadena = ConfigurationManager.ConnectionStrings["OracleDbContext"].ConnectionString;
OracleConnection con = new OracleConnection(cadena);
OracleCommand cmd = new OracleCommand(queryRoles, con);
cmd.Parameters.Add(new OracleParameter("ExpCodigo", string.IsNullOrEmpty(nuevoExpediente) ? int.Parse(ExpedienteGeneral) : int.Parse(nuevoExpediente)));
cmd.Parameters.Add(new OracleParameter("fechaSolicitud", DateTime.Parse(fechaSolicitud)));
cmd.Parameters.Add(new OracleParameter("fechaEstado", DateTime.Parse(fechaEstado)));
cmd.Parameters.Add(new OracleParameter("pais", int.Parse(pais)));
#region Procedimiento
try
{
con.Open();
Permisos.OtorgarPermisos(con);
using (OracleDataReader dr = cmd2.ExecuteReader())
{
while (dr.Read())
{
//make an insert or update into database
}
}
}
catch (Exception ex)
{
//and here when i catch the exception show the message in the view
}
finally
{
if (con.State == System.Data.ConnectionState.Open)
{
con.Close();
con.Dispose();
cmd.Dispose();
}
}
#endregion
return RedirectToAction("RegistroMarca");
});
}
All i need is if the method action of controller catch an exception show the exact type of exception into a message and display into a view. If it's possible like an alerts message of bootstrap like this:
<div class="alert alert-success" id="mostrarAlertSuccess" style="display:none; margin-top:10px">
<strong>¡Eliminación exitosa!</strong> El registro fue eliminado correctamente.
</div>
<div class="alert alert-danger" id="mostrarAlertDanger" style="display:none; margin-top:10px">
<strong>Danger!</strong> Indicates a dangerous or potentially negative action.
</div>
I Would use TempData["key"]
This is like ViewData["key"] however the data persists for the next HttpRequest and is disposed automatically by asp.net after this
Controller Action
[HttpPost]
public ActionResult SomePostAction(SomeViewModel vm)
{
if(ModelState.IsValid) // Is User Input Valid?
{
try
{
CommitData();
TempData["UserMessage"] = new { CssClassName = "alert-sucess", Title = "Success!", Message = "Operation Done." };
return RedirectToAction("Success");
}
catch(Exception e)
{
TempData["UserMessage"] = new { CssClassName = "alert-error", Title = "Error!", Message = "Operation Failed." };
return RedirectToAction("Error");
}
}
return View(vm); // Return View Model with model state errors
}
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
</head>
<body>
#if(TempData["UserMessage"] != null)
{
<div class="alert #TempData["UserMessage"].CssClassName">
<strong>#TempData["UserMessage"].Title</strong> #TempData["UserMessage"].Message
</div>
}
#RenderBody()
</body>
</html>