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

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

Related

Cannot read property 'setValue' of undefined | Angular

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.

I cannot submit angular reactive form in a ngb modal Angular 7

I am trying to create a form in a NgbModal, I can open an initialize the form however when I press submit button, nothing happens.
Here is HTML code;
<ng-template #content let-c="close" let-d="dismiss">
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Give your feedback</h4>
</div>
<form [formGroup]="addForm" (ngSubmit)="onSubmit()">
<div class="modal-body">
<div class="form-group">
<label>Title</label>
<input type="text" formControlName="title" class="form-control" [ngClass]="{ 'is-invalid': submitted && addForm.controls.title.errors }" />
<div *ngIf="submitted && addForm.controls.title.errors" class="invalid-feedback">
<div *ngIf=" addForm.controls.title.errors">* Title is required</div>
</div>
</div>
<div class="form-group">
<label>Comment</label>
<textarea type="text" rows="4" cols="50" formControlName="text" class="form-control" [ngClass]="{ 'is-invalid': submitted && addForm.controls.text.errors }"></textarea>
<div *ngIf="submitted && addForm.controls.text.errors" class="invalid-feedback">
<div *ngIf=" addForm.controls.text.errors">* Comment is required</div>
</div>
</div>
<div class="form-group">
<label>Rate</label><br>
<ngb-rating formControlName="rate" max="5" [starTemplate]="rate">
</ngb-rating>
</div>
</div>
<div class="modal-footer">
<button style="margin-left: 5px" type="submit" class="btn btn-success pull-right">Save</button>
<button type="button" class="btn btn-outline-danger pull-right" (click)="c('cancelled')">Cancel</button>
</div>
</form>
</ng-template>
<ng-template #rate let-fill="fill" let-index="index">
<span class="star" [class.filled]="fill === 100">★</span>
</ng-template>
<ng-template #rate let-fill="fill" let-index="index">
<span class="star" [class.filled]="fill === 100">★</span>
</ng-template>
<button *ngIf="authService.currentUserValue" type="button" style="height: 50px" (click)="open(content)" class="btn btn-outline-primary pull-right" data-toggle="modal">
give your feedback
</button>
My open button works fine and also I can close modal, but somehow save is not working. Additionally my onSubmit method is like;
onSubmit() {
this.submitted = true;
const data = {
productId:this.currentProduct.productId,
userId: this.authService.currentUserValue.userId,
title: this.addForm.controls.title.value,
text: this.addForm.controls.text.value,
rating: this.addForm.controls.rating.value,
};
this.loading = true;
this.commentService.addComment(data).subscribe(
data => {
this.success = true;
this.router.navigate(['/']);
},
error => {
this.error = error;
this.loading = false;
}
)
}
No error is thrown or no action happens, clicking is not working. How can I fix this?
Your component doesn't know which modal to close. You need to pass the NgbModal reference to the submission function.
<form [formGroup]="addForm" (ngSubmit)="onSubmit(content)">
'content' refers to the template reference of the modal.
onSubmit(modal: NgbModal) {
modal.dismiss(); // Add wherever you need
}
And just as a heads up, if you...
<form [formGroup]="addForm" (ngSubmit)="onSubmit()" #f="ngForm"> /* Last attribute added */
and then create add a ViewChild before the constructor...
#ViewChild('f') ngForm: NgForm;
you'll be able to access ngForm's submission status by this.ngForm.submitted rather then setting them yourself manually. Angular docs for NgForm

How to fill fields with a single click on a table row with ReactJS

I am making an react application with a simple CRUD functionality. In my environment I use a framework called react bootstrap 2.
Link: https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/getting-started.html
I have a form that the user can fill the information:
<form id="car-form" onSubmit={this.handleSubmit}>
<input type="hidden" name="carId" />
<div className="row">
<div className="form-group col-sm-3">
<label>Brand</label>
<input type="text" className="form-control" placeholder="Enter brand" value={this.state.brand} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>Model</label>
<input type="text" className="form-control" placeholder="Enter model" value={this.state.model} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>Color</label>
<input type="text" className="form-control" placeholder="Enter color" value={this.state.color} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>TopSpeed</label>
<input type="number" className="form-control" placeholder="Enter speed" value={this.state.topSpeed} onChange={this.handleChange} />
</div>
</div>
<div className="btn-group mr-2">
<button type="submit" className="btn btn-danger mr-1">Save changes</button>
<button type="reset" className="btn btn-danger mr-1">New record</button>
<button type="submit" className="btn btn-danger mr-1">Delete record</button>
</div>
</form>
The user can add a car and this working fine with the .NET core backend. I have a function from the official react bootstrap 2 documentation to select a row.
const rowEvents = {
onClick: (e, row, rowIndex) => {
console.log(`clicked on row with index: ${rowIndex}`);
}
};
When I click on a row I get the right index number. Now when I click on a row I want to fill the fields with data.
This is my handleChange method
handleChange(event) {
this.setState({
brand: event.target.brand,
model: event.target.model,
color: event.target.color,
topspeed: event.target.top
})
};
It still doesn't work when I click on a row.
How can I fill the fields when I click on a row?
Solution I used:
How do I programatically fill input field value with React?
assuming this.state.cars is where you storing the cars data . On clicking on the row change your function to
const rowEvents = {
onClick: (e, row, rowIndex) => {
this.setState({
brand: this.state.cars[rowIndex].brand,
model: this.state.cars[rowIndex].model,
color: this.state.cars[rowIndex].color,
topspeed: this.state.cars[rowIndex].top
})
}
};
and copy your rowEvents to render()

How to redirect to another ui-sref page in angularjs and show second page and first page hide?

when i redirect by using (ui-view) i face like this you can see image...
but i want to redirect to second page and login page should be hide using ui-view?
html code:here you can see
<div class="log-w3" ng-app="log" ng-controller="logcontroller">
<div class="w3layouts-main">
<h2>Sign In Now</h2>
<input type="text" ng-model="log.UserName" class="ggg" name="UserName" placeholder="E-MAIL" required="">
<input type="password" id="txtpassword" class="ggg" ng-model="log.Password" name="Password" placeholder="PASSWORD" required="">
<span><input type="checkbox" />Remember Me</span>
<h6>Forgot Password?</h6>
<div class="clearfix"></div>
<input type="submit" ng-click="login(log)" value="Sign In" name="login">
<img src="~/Design/images/loader.gif" id="loader" width="80" height="80" />
<div class="alert alert-success alert-dismissible" id="msg">
<strong>Success!</strong> Congraculation You Have Successfully Login!
</div>
<div class="alert alert-danger alert-dismissible" id="error">
×
<strong>Danger!</strong> Invalid Username or Password!
</div>
<p>Don't Have an Account ?Create an account</p>
</div>
<ui-view></ui-view>
</div>
angular js code:you can see the angular js code i use $state.go
.controller('logcontroller', function ($scope, Notification, $state, $http, cfpLoadingBar) {
$scope.login = function (log) {
$http.post("/Login/Info", log).then(function (response) {
cfpLoadingBar.start();
//console.log(JSON.stringify(response))
if (response.data.success) {
console.log('Login sucessfull');
Notification.success(response.data.message)
$state.go("/Log");
} else {
//alert(response.data.message)
Notification.error(response.data.message)
}
cfpLoadingBar.complete();
}, function () {
alert("Wrong ha")
})
}
})
.config(function ($stateProvider) {
$stateProvider
.state("/Log",
{
url: "Welcome",
templateUrl: "/Dash/Index"
})
});

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.