Cannot read property 'errors' of undefined in angular 2 - html

I am validating my template using angular2, but meanwhile it shows this error:
Cannot read the property 'errors' of undefined.
Here is my template:
<h3 class = "head">{{title}}</h3>
<form [ngFormModel]="form" #f="ngForm">
<div class="row">
<div class="form-group">
<label class="formHeading">Facebook</label>
<input type="text" id="facebook" class="form-control col-xs-3" ngControl="facebook" #facebook="ngForm" >
</div>
<div *ngIf ="facebook.touched && facebok.errors">
<div class="form-row btn">
<button type="submit" class="btn btn-primary pull-right butspace" [disabled]="!f.valid">Save</button>
</div>
</div>
</form>
I dont know why it shows this error. Can anyone fix it?

First of all, you have facebok instead of facebook on the error property.
If that doesn't fix it you're probably using the facebook object before it is assigned, which can happen if it's an #Input() for example.
Use the Elvis operator:
*ngIf ="facebook?.touched && facebook?.errors"

Related

Displaying Textbox Information and updating in Angular and TS

Fairly new to stack overflow but I needed assistance.
I did a backend and the API is working fine after tests from postman.
I can add employee and I can retrieve employee. However, what I am trying to do is, when I click on the card, I want the card I clicked on to display information about the employee in the textboxes and allow me to change and update. I am failing to retrieve and update my HTML. Please help.
In MY TS, I have this:
updateEmployee(employee: Employee){this.load = true;this.users.updateEmployee(employee).subscribe(res => {this.load = false;this.onPrimaryOutline("Employee has been updated");this.getEmployee();},err=>{console.log(err);this.load = false;this.onErrorOutline("Failed to update Employee, please try again");});}
onOpenModal(employee: Employee, mode: string): void {const containerUpdate = document.getElementById('update-container');const button = document.createElement('button');button.type = 'button';button.style.display = 'none';button.setAttribute('data-toggle', 'modal');if (mode === 'save'){this.updateEmployee = employee;button.setAttribute('data-target', '#update-container');}if (mode === 'delete'){button.setAttribute('data-target', '#deleteEmployeeMasterModal');} containerUpdate.appendChild(button);
button.click()}
service:
public updateEmployee(employee: Employee): Observable<Employee>{ return this.http.put<Employee>(${this.updateEmployee_url}/employee/update, employee) }
HTML:
<div class="card" id="update-container" [hidden]="!showForm" data-toggle="modal" data-target="#updateEmployeeModal"><span aria-hidden="true">×</span><ng-template #template><ngx-loading-x [show]="load"></ngx-loading-x><div NgxLoadingXBlur [show]="load"><div class="modal-header">
<div>
<button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
<span aria-hidden="true">×</span> </button>
</div>
<div class="modal-body">
<div class="card mb-4">
<div class="card-body">
<h6 class="mb-4">{{ 'forms.external-components' | translate }}
</h6>
<form [formGroup]="commonForm" #editForm="ngForm" (ngSubmit)="updateEmployee()" novalidate class="tooltip-label-right">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" name="name" ngModel="{{editEmployee?.name}}" formControlName="name">
<small>Only letters and at least 2 characters</small>
<div *ngIf="commonForm.get('name')?.errors?.required && !form.submitted" class="invalid-tooltip">Name is required!</div>
</div>
<div class="form-group">
<label>Surname</label>
<input type="text" class="form-control" name="airlineCode" ngModel="{{editEmployee?.surname}}" formControlName="surname">
<small>Only letters and at least 2 characters</small>
<div *ngIf="commonForm.get('surname')?.errors?.required && !form.submitted" class="invalid-tooltip">Code is required!</div>
</div>
<div class="form-group">
<label>Number</label>
<input type="text" class="form-control" name="phonenumber" ngModel="{{editEmployee?.phonenumber}}" formControlName="phonenumber">
<div *ngIf="commonForm.get('phonenumber')?.errors?.required && !form.submitted" class="invalid-tooltip">Number is required!</div>
</div>
<button class="btn btn-primary" type="submit" [disabled]="!commonForm.valid" (click)="updateEmployee(employee, Employee)" (click)="modalRef.hide()">Update</button>
<button type="button" class="btn btn-danger" style="display: inline-block;margin-left: 20px;" (click)="delete()" (click)="modalRef.hide()">Delete</button>
</form>
</div>
</div>
</div>
</div>
I just need to retrieve the values for the specific card when I click on it and be able to update it. But I cannot see what I am omitting. Inspect element says:
ngModel cannot be used to register form controls with a parent formGroup directive. Try using
formGroup's partner directive "formControlName" instead

Angular 2+: Error: Unexpected closing tag "div" - Uncaught Error: Template parse errors

I've been staring and toying with this html code block for a simple Angular 4 page, and no matter what I do, looking for typos and searches on the errors it keeps giving me a hard time with my closing tags.
Error Message:
Uncaught Error: Template parse errors:
Unexpected closing tag "div". It may happen when the tag has already been closed by another tag. /div> /div> [ERROR ->]/div>
<form [formGroup]="form">
<!-- OLD PASSWORD -->
<div class="form-group">
<label for="">Old Password</label>
<input formControlName="oldPassword" type="password" class="form-control">
<div
*ngIf="oldPassword.touched && oldPassword.invalid"
class="alert alert-danger">
<div *ngIf="oldPassword.errors.required">
Old password is required.
</div>
</div>
</div>
<!-- NEW PASSWORD -->
<div class="form-group">
<label for="">New Password</label>
<input formControlName="newPassword" type="password" class="form-control">
<div
*ngIf="newPassword.touched && newPassword.invalid"
class="alert alert-danger">
<div *ngIf="newPassword.errors.required">New password is required.</div>
</div>
</div>
<!-- CONFIRM PASSWORD -->
<div class="form-group">
<label for="">Confirm Password</label>
<input formControlName="confirmPassword" type="password" class="form-control">
<div
*ngIf="confirmPassword.touched && confirmPassword.invalid"
class="alert alert-danger">
<div *ngIf="confirmPassword.errors.required">Confirm password is required.</div>
</div>
</div>
<button class="btn btn-primary">Change Password</button>
</form>
[SOLVED] after pretty much turning this project upside-down and inside-out it seems my problem was that I had two components that were very similarly named:
"change-password"
and then
"change-password-reactive"
I had to removed the instance of "change-password" from my app.module.ts to get the page to load and this error to go away.

input field or help text doesn't turn red when field is invalid

I used to implement an Angular 2/4 application with Bootstrap 3 and used the Reactive Forms approach. I had a field-validation where the border of the input-field turned red and an error message appeared under the field in red font color.
it looks like this:
<div class="form-group row"
[ngClass]="{'has-error': (sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
!sourcesForm.get('sourceName').valid }">
<label class="col-md-2 col-form-label"
for="sourceNameId">Source Name</label>
<div class="col-md-8">
<input class="form-control"
id="sourceNameId"
type="text"
placeholder="Source Name (required)"
formControlName="sourceName" />
<span class="help-block" *ngIf="(sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
sourcesForm.get('sourceName').errors">
<span *ngIf="sourcesForm.get('sourceName').errors.required">
Please enter the Source Name.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.minlength">
The Source Name must be longer than 3 characters.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.maxlength">
The Source Name is too long.
</span>
</span>
</div>
</div>
Now i have to use Bootstrap 4 and neither the error message or the input-field turns red. How do i realise this? I tried to change the class of the parent span-block to "form-text" but it didn't work.
For beta version of Bootstrap v4, you can check out Form validation docs. There you can read about the new way, supported by all modern browsers for HTML5 way of form-validation with valid/invalid css classes. There Bootstrap uses the .was-validated and .invalid-feedback classes for what you want to achieve (see code snippet).
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
<form class="container" id="needs-validation" novalidate>
<label for="validationCustom02">Last name</label>
<input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required>
<label for="validationCustom03">City</label>
<input type="text" class="form-control" id="validationCustom03" placeholder="City" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
"use strict";
window.addEventListener("load", function() {
var form = document.getElementById("needs-validation");
form.addEventListener("submit", function(event) {
if (form.checkValidity() == false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
}, false);
}, false);
}());
</script>
If you want something more similar to Bootstrap 3, you can use what they call server-side validation, as it is written:
As a fallback, .is-invalid and .is-valid classes may be used instead of the pseudo-classes for server side validation. They do not require a .was-validated parent class.
Previous answer for alpha version of Bootstrap V4 (if you must use this).
On Bootstrap V4 Form Validation Docs there is the following example:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="form-group has-danger">
<label class="form-control-label" for="inputDanger1">Input with danger</label>
<input type="text" class="form-control form-control-danger" id="inputDanger1">
<div class="form-control-feedback">Sorry, that username's taken. Try another?</div>
<small class="form-text text-muted">Example help text that remains unchanged.</small>
</div>
So i think you just need to change the has-error class to has-danger
This is the solution:
<div class="form-group row">
<label class="col-md-2 col-form-label"
for="sourceNameId">Source Name</label>
<div class="col-md-8">
<input class="form-control"
[ngClass]="{'is-invalid': (sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
!sourcesForm.get('sourceName').valid }"
id="sourceNameId"
type="text"
placeholder="Source Name (required)"
formControlName="sourceName" >
<span class="invalid-feedback" *ngIf="(sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
sourcesForm.get('sourceName').errors">
<span *ngIf="sourcesForm.get('sourceName').errors.required">
Please enter the Source Name.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.minlength">
The Source Name must be longer than 3 characters.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.maxlength">
The Source Name is too long.
</span>
</span>
</div>
</div>
i needed to put the [ngClass]into the input-tag. Then i had to define the class as is-invalid and set the parent span-class to invalid-feedback
i know that your question is for long time ago, but it is the best way to validate the form-control input field by reactive form technique and bootstrap 4 to display the validation. first you need to write some code for your form :
in html section:
<form [formGroup]="myForm">
<div class="form-group">
<label for="name">first Name: </label>
<input type="text" class="form-control" formControlName="firstName" id="name">
<div *ngIf="firstName.touched && firstName.invalid" class="alert alert-danger">
<div *ngIf="firstName.errors.required">filling name is required!</div>
</div>
</div>
in ts file, you should implement the logic to conduct the validation.
in ts file:
myForm = new FormGroup({
'firstName':new FormControl('',Validators.required)
})
//getter method
get firstName(){
this.myForm.get('firstName');
}
now you can see that the validation is working. now to give style to input field to show the red border around the invalid input, just go to css file of component and add this class to the css file:
.form-control.ng-touched.ng-invalid{border:2px solid red;}
and simply you can see the result.

How to loop input field based on array

I have an array like below
standardInput:any = [{val:'1'},{val:'2'},{val:'3'}];
When i loop it in my view
<div class="form-group row text-right" *ngFor='let row of standardInput' >{{row.val}}
<label class="col-sm-3 form-control-label m-t-5" for="password-h-f"></label>
<div class="col-sm-9 form-control-label m-t-5" for="password-h-f">
<div class="row">
<div class="col-sm-9" >
<input class="form-control" name="roles" [formControl]="form.controls['service_standard_sub_heading']" [(ngModel)]="row.val" id="email-h-t" type="email">
</div>
<div class="col-sm-3">
<button class="btn btn-danger" (click)="removeInputs('standard',i)">Remove</button>
</div>
</div>
</div>
</div>
The output is :3 3 3,it is showing only the last object in the array for the 3 iterations.I am not able to understand what's the reason.Can anyone please suggest help.Thanks.
I believe you are using template-driven form, if not, let me know and we can look at a solution for model-driven form :)
In forms, the name attribute needs to be unique. Even though the ngModel is unique, Angular doesn't really care about it, but looks at the name attribute instead. Since you are using a template-driven form and ngModel, I see no need to use formControl here, you can just rely on the the ngModel and name attribute instead. So, to get the unique name attribute, we can bind the row.val to it, like so:
[name]="row.val"
So your complete template would look like this:
<form #form="ngForm">
<div class="form-group row text-right" *ngFor='let row of standardInput'>
<input class="form-control" [name]="row.val" [(ngModel)]="row.val">
</div>
</form>

Strange error html form

I'm using this code for a form in HTML:
<div class="login-wrapper">
<form>
<div class="popup-header">
<span class="text-semibold"><i class="fa fa-sign-in"></i> Logging in</span>
</div>
<div class="well">
<div class="form-group has-feedback">
<label>Username</label>
<input type="text" name="user" class="form-control" placeholder="e.g. andre#mail.de">
<i class="icon-users form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label>Password</label>
<input type="password" name="password" class="form-control" placeholder="Password">
<i class="icon-lock form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label>reCaptcha</label>
<div class="g-recaptcha" data-sitekey="..."></div>
</div>
<div class="form-actions text-right">
<input type="submit" id="loginbutton" name="loginbutton" value="Login" class="btn btn-primary">
</div>
</div>
</form>
</div>
<!-- /login wrapper -->
However, when I press the submit button, it does nothing but giving me a very strange url in my browser's address bar:
http://localhost/?user=&password=&g-recaptcha-response=&loginbutton=Login
Whenever I fill out fields, it kind of puts the content into the URL:
http://localhost/?user=peter%40griffin.com&password=somepass&g-recaptcha-response=&loginbutton=Login
The intended PHP code which should be run when pressing the button won't even run or load, since this HTML stuff apparently screws things up. I don't know what I have done the wrong way. Any suggestions?
In order for the form to submit somewhere else, you need to set the form elements action parameter.
<form action="some_file.php">
Alternatively, you can take the query string and append it directly to the file path to test your script.
http://localhost/some_file.php?user=peter%40griffin.com&password=somepass&g-recaptcha-response=&loginbutton=Login
Inside of some_file.php, you would then pull out each of the variables like
$user = $_GET['user'];
$password = $_GET['password'];
The very strange url is actually the result of a GET request.
The parameters are separated by an & so you have:
user=peter%40griffin.com&password=somepass&g-recaptcha-response=
"User" is the attribute name of your input and "peter%40griffin.com" is the value
First you need to send your form to an action using the attribute action="save.php", for example an pass the parameters using the method="POST", so the user can't see the values in the URL.
<form action="save.php" method="post">