Cannot read property 'setValue' of undefined | Angular - html

I am having an issue with my HTML component, for some reason the my method is displaying an error:
Cannot read property 'setValue' of undefined when I click the edit button, however everything seems to be ok.
This is my HTML
<div *ngFor="let item of currentUser.myExperiences" class="mt-3">
<div>
<h6>{{item.companyName}} <span *ngIf="item.currentlyWorking" class="badge badge-warning">Currently
working</span>
<span class="float-right">
<a class="text-warning cursor" (click)="openEditModal(item)"><i class="fas fa-pencil-alt"></i></a>
</span>
</h6>
<p class="text-muted p-text-sm">{{item.functions}}</p>
<p class="text-muted p-text-sm" *ngIf="item.references">
<strong>References:</strong>
{{item.references}}
</p>
<hr>
</div>
</div>
<form role="form" [formGroup]="updateForm">
<div class="form-group">
<label for="functions">Funtions</label>
<input type="text" class="form-control" id="functions" name="functions" formControlName="functions" aria-describedby="emailHelp">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
This is my TS component:
public openEditModal(myExperience: IMyExperience): void {
console.log(myExperience);
// Set values to controls
console.log(myExperience.id);
this.experienceId.setValue(myExperience.id);
this.companyName.setValue(myExperience.companyName);
this.functions.setValue(myExperience.functions);
this.workedYears.setValue(myExperience.workedYears);
this.references.setValue(myExperience.references);
this.currentlyWorking.setValue(myExperience.currentlyWorking);
this.updateForm.setValue({
experienceId: this.experienceId.value,
companyName: this.companyName.value,
functions: this.functions.value,
workedYears: this.workedYears.value,
references: this.references.value,
currentlyWorking: this.currentlyWorking.value
});
// Open the modal
this.modalRef = this.modalService.show(
this.editModal,
Object.assign({}, { class: 'gray modal-lg' })
);}
I tried displaying in console the object, but it works perfectly, however I am not sure why this is happening.
I use resolvers to pass information from the route to the component properly.
Thanks in advance.

Try to use this.updateForm.patchValue instead of this.updateForm.setValue.

Related

The GET method is not supported for this route. Supported methods: POST in Laravel livewire

Sorry, I have a routes problem in laravel livewire. I want to test my login form validation on my website by continuously clicking the submit button (after giving a response of course), and on the fifth (5) click I have a problem "The GET method is not supported for this route. Supported methods: POST". Does anyone know about this problem? Because I also tried it on a simple form on localhost and there was no error.
I use laravel livewire 2.2
This is the code on my website,
Blade
<form wire:submit.prevent="check">
<div class="form-group">
<label class="label">Email</label>
<div class="input-group">
<input wire:model.defer="email" type="email" class="form-control" placeholder="xxx#xxx.xx">
<div class="input-group-append">
<span class="input-group-text">
<i class="mdi mdi-check-circle-outline"></i>
</span>
</div>
</div>
#error('email')<label class="text-danger">{{ $message }}</label> #enderror
</div>
<div class="form-group">
<label class="label">Password</label>
<div class="input-group">
<input wire:model.defer="password" type="password" class="form-control" placeholder="**********">
<div class="input-group-append">
<span class="input-group-text">
<i class="mdi mdi-check-circle-outline"></i>
</span>
</div>
</div>
#error('password')<label class="text-danger">{{ $message }}</label> #enderror
</div>
<div class="form-group">
<button class="btn btn-success submit-btn btn-block" wire:loading.attr="disabled" >
<div wire:loading.remove>Login</div>
<div wire:loading>
<div class="loading-bar bg-white"></div>
<div class="loading-bar bg-white"></div>
<div class="loading-bar bg-white"></div>
<div class="loading-bar bg-white"></div>
</div>
</button>
</div>
</form>
Controller
class Login extends Component
{
public $password;
public $email;
protected $rules = [
'password' => 'required',
'email' => 'required|email',
];
public function check()
{
$this->validate($this->rules);
if (Auth::attempt(['email' => $this->email, 'password' => $this->password]))
{
redirect()->to('livewire/add');
}else
{
$this->dispatchBrowserEvent('alert', ['type' => 'error', 'title' => 'Error','message' => 'Credential not valid']);
}
}
public function render()
{
return view('livewire.login')->extends('backend.v2.master');
}
}
Routes
Route::group(['prefix' => 'livewire'], function() {
Route::get('/login',Login::class);
Route::get('/add',Add::class);
});
First submit
image
Error result after the fifth click
image
Thanks for your help.
Have you tried wrapping the whole form in a div element?
<div>
{{-- Anything you want to do --}}
</div>

Angular 6 - click to make a div editable

Using Angular 6, I have the html below and would like to click the edit text to make the div containing Detail$.Title editable.
Im trying to do it as per this SO post
<div class="col-sm-6">
<div class="card text-left" >
<div class="card-header text-secondary">Title <small class="pull-right text-danger" (click)="setTitleEdit()">Edit Text</small></div>
<div class="card-body">
<span *ngIf="!cd.canEditCode">{{Detail$.Title}}></span>
<input *ngIf="cd.canEditCode" type="text" class="form-control" />
<p class="card-text text-secondary">{{ Detail$.Title}}</p>
</div>
</div>
intellisense doesn't like the forEach or canEditCode below, I know Im missing something, just not sure what, Im unsure where the canEditCode is coming from in the linked post. In my ts file Detail$ is an object containing the data returned from a call
getEventDetail(): void {
this.data.getDetail(this.id)
.subscribe(data => this.Detail$ = data);
}
setTitleEdit(){
this.Detail$.forEach(t => t.canEditCode = false)
this.Detail$.canEditCode=true
}
try like this
<div class="col-sm-6" *ngFor="let item of detailItems">
<div class="card text-left">
<div class="card-header text-secondary">{{item.title}}
<small class="pull-right text-success" (click)="item.canEditCode = true">Edit</small>
<small class="pull-right text-danger" (click)="item.canEditCode = false">Close</small>
</div>
<div class="card-body">
<span>{{item.name}}</span>
<input *ngIf="item.canEditCode" [(ngModel)]="item.name" type="text" class="form-control" />
</div>
</div>
[(ngModel)]="item.name" make two way binding to item property (name)
stackblitz demo
I think it's easier to use native HTML input for editing and viewing with ngModel and style options.
Simply like this:
<input type="text" [(ngModel)]="title" class="editable">
And for CSS class:
.editable{
border:none;
outline:none;
background:transparent;
}
That's should work.

Get values of dynamic input fields

I have this HTML template:
<div class="container">
<div class="row">
<div class="col-md-12">
<div data-role="dynamic-fields">
<div class="form-inline">
<div class="form-group">
<label class="sr-only" for="field-name">Link </label>
<input type="text" class="form-control" id="field-name" placeholder="Link"
[(ngModel)]="HrefLink" name="HrefLink">
</div>
<span>-</span>
<div class="form-group">
<label class="sr-only" for="field-value">Label</label>
<input type="text" class="form-control" id="Label" placeholder="Label"
[(ngModel)]="HrefLabel" name="HrefLabel">
</div>
<button class="btn btn-danger" data-role="remove">
<span class="glyphicon glyphicon-remove"></span>
</button>
<button class="btn btn-primary" data-role="add">
<span class="glyphicon glyphicon-plus"></span>
</button>
</div> <!-- /div.form-inline -->
</div> <!-- /div[data-role="dynamic-fields"] -->
</div> <!-- /div.col-md-12 -->
</div> <!-- /div.row -->
</div>
In this simple form, I can add one or more inputs. This is the live example: https://bootsnipp.com/snippets/VPRlZ
My question is: How can I get the values of all added fields inside my angular component ? I can add the directive ngModel like above in every input but then all directives will have the same name and I'll not get all values?
Unfortunately, I can't place the ngModel in a higher level in the div of form-group ...
Please tell me if my question is clear or you need more information.
Why not you base the quantity of input in an array of Objects(InputModel it is a custom interface or class) and finally use *ngfor to show them.
InputModel
{
input_value: string,
index_of: number,
isDelete: boolean, //if false is "+" if true is "x"
}
Component.ts
inputValues: InputModel[] = [];
count: number = 0;
OnInit{
this.inputValues.push({
input_value:"",
index_of: this.count,
isDelete: true
});
}
addMore(){
this.inputValues.push({
input_value:"",
index_of: this.count++,
isDelete: false
});
}
Html Template
<div *ngFor="let input of inputValues">
<input [(ngModel)]="input.input_value" />
<!-- TODO button with 'x' or '+' depends of input.isDelete -->
</div>

[ng-bootstrap]: Open modal after calling api, ExpressionChangedAfterItHasBeenCheckedError

i'm using Angular, express (node).
I am opening a modal after validating the user's data at login (httpClient - express).
But when I open the modal (yes, the modal opens) I get an exception in the console:
ExpressionChangedAfterItHasBeenCheckedError:
Expression has changed after it was checked. Previous value:
'ng-untouched: true'. Current value: 'ng-untouched: false'.
Here is my basic code:
example.html
<ng-template #modalexample let-c="close" let-d="dismiss">
/** modal body **/
</ng-template>
form (ngSubmit)="f.form.valid && signin()" #f="ngForm" class="m-login__form m-form" action="">
<ng-template #alertSignin></ng-template>
<div class="form-group m-form__group">
<input class="form-control m-input" type="text" placeholder="Email" name="email" [(ngModel)]="model.email" #email="ngModel" autocomplete="off">
</div>
<div class="form-group m-form__group">
<input class="form-control m-input m-login__form-input--last" type="password" placeholder="Password" name="password" [(ngModel)]="model.password" #password="ngModel">
</div>
<div class="row m-login__form-sub">
<div class="col m--align-left">
<label class="m-checkbox m-checkbox--focus">
<input type="checkbox" name="remember" [(ngModel)]="model.remember" #remember="ngModel">
Remember me
<span></span>
</label>
</div>
<div class="col m--align-right">
<a href="javascript:;" id="m_login_forget_password" class="m-link">
Forget Password ?
</a>
</div>
</div>
<div class="m-login__form-action">
<button [disabled]="loading" [ngClass]="{'m-loader m-loader--right m-loader--light': loading}" id="m_login_signin_submit" class="btn btn-focus m-btn m-btn--pill m-btn--custom m-btn--air">
Sign In
</button>
</div>
</form>
And my component.ts
#ViewChild('modalexample', {read: TemplateRef}) modal: TemplateRef<any>;
signin() {
console.log("Signin")
this.modalService.open(this.content);
this.loading=true;
this._authUser.login(this.model.email, this.model.password).subscribe(
response=>{
if(!response.error){
this.loading=false;
}
else{
alert('Error');
}
this.loading=false;
},
error=>{
console.log(error)
this.loading=false;
}
)
}
How can I solve it?
Thank you :D

Refresing the page on (submit) process Angular2 & Firebase

I´m trying to apply Firebase to the Admin HTML template that I found yesterday.
In the register page when I click on Sign in it reload the page instead of do the Firebase createUserWithEmailAndPass process.
This is my HTML code:
<form [formGroup]="form" (submit)="registrar(form.value)" class="form-horizontal">
<div class="form-group row" [ngClass]="{'has-error': (!name.valid && name.touched), 'has-success': (name.valid && name.touched)}">
<label for="inputName3" class="col-sm-2 control-label">Nombre</label>
<div class="col-sm-10">
<input [formControl]="name" type="text" class="form-control" id="inputName3" placeholder="Nombre completo">
</div>
</div>
<div class="form-group row" [ngClass]="{'has-error': (!email.valid && email.touched), 'has-success': (email.valid && email.touched)}">
<label for="inputEmail3" class="col-sm-2 control-label">NIF</label>
<div class="col-sm-10">
<input [formControl]="email" type="text" class="form-control" id="inputEmail3" placeholder="NIF/DNI">
</div>
</div>
<div class="form-group row" [ngClass]="{'has-error': (!password.valid && password.touched), 'has-success': (password.valid && password.touched)}">
<label for="inputPassword3" class="col-sm-2 control-label">Contraseña</label>
<div class="col-sm-10">
<input [formControl]="password" type="password" class="form-control" id="inputPassword3" placeholder="Introduce una contraseña">
</div>
</div>
<div class="form-group row" [ngClass]="{'has-error': (!repeatPassword.valid && repeatPassword.touched), 'has-success': (repeatPassword.valid && repeatPassword.touched)}">
<label for="inputPassword4" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input [formControl]="repeatPassword" type="password" class="form-control" id="inputPassword4" placeholder="Repite la contraseña">
<span *ngIf="!passwords.valid && (password.touched || repeatPassword.touched)" class="help-block sub-little-text">Las contraseñas no coinciden.</span>
</div>
</div>
<div class="form-group row">
<div class="offset-sm-2 col-sm-10">
<button [disabled]="!form.valid" type="submit" class="btn btn-default btn-auth">Confirmar registro</button>
</div>
</div>
</form>
And this my functions:
nuevoUsuario(email, password) {
console.log(email);
return this.af.auth.createUser({
email: email,
password: password
});
}
public registrar(datos: Object): void {
this.submitted = true;
if (this.form.valid) {
// your code goes here
const formarCorreo = this.email.value +' #maimona.com';
console.log(formarCorreo);
this.afService.nuevoUsuario(formarCorreo.toLowerCase,
this.password).then((user) => {
this.afService.saveUserInfoFromForm(formarCorreo.toLowerCase,
this.name, this.email).then(() => {
// this.router.navigate(['login']);
})
.catch((error) => {
this.error = error;
console.log(error);
});
})
.catch((error) => {
this.error = error;
console.log(error);
});
}
}
I don´t know why when I press "Confirmar registro" it reload the page instead of do the function. Well it enter the function until
console.log(formarCorreo);
You can change the type of the button to button from submit and add the function to the buttons click
<button [disabled]="!form.valid" class="btn btn-default btn-auth"
type="button" <-- type
(click)="registrar(form.value)" <--click
>Confirmar registro</button>
type="submit will make elements to reload the form
By default, html <form> elements navigate to their target attribute.
To override this (since this is what you'll want most of the time in a single-page app), angular provides the (ngSubmit) convenience event (which uses event.preventDefault(), which would solve your case anyway, but is cleanear)
<button type="submit"> is doing HTTP request to the server. It's the same like <input type="submit">.
You can change it to ordinary <button> or prevent the submitting a form using events.