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
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>
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.
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>
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
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.