Reputation: 325
I use firebase and angular 2+. In my app I have a login page. When I click 'sign in' button, the spinner is loading and after success, it should be false, but it doesn't update. Why?
Template
<div class="sign-in-form-buttons-section">
<div>{{isLoadingInProgress}}</div>
<button
*ngIf="!isLoadingInProgress; else loading"
mat-raised-button
color="primary"
(click)="onSignInClicked()"
>
Sign In
</button>
<ng-template #loading>
<mat-spinner></mat-spinner>
</ng-template>
</div>
Controller
public signInFormGroup: FormGroup;
public isLoadingInProgress: boolean = false;
constructor() {
this.signInFormGroup = new FormGroup({
email: new FormControl(''),
password: new FormControl(''),
});
}
public onSignInClicked(): void {
this.isLoadingInProgress = true;
const signInInfo: SignInInfo = {
email: this.signInFormGroup.value.email,
password: this.signInFormGroup.value.password
};
this.authService.signInWithEmailAndPassword(
signInInfo.email,
signInInfo.password,
)
.then(() => {
this.isLoadingInProgress = false;
})
.catch(error => {
this.snackBarService.showSnackBar(error.message);
this.isLoadingInProgress = false;
});
}
Upvotes: 0
Views: 126
Reputation: 21
Yes, It happens because Angular Doesn't check every non-local variable for performance issues. For Http request, angular can't detect in one Process/Thread.
Solution:
You can use the RxJS BehaviorSubject
method.
For Example:
loader.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class LoaderService {
public status: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
display(value: boolean) {
console.log('LoaderService.display ' + value);
this.status.next(value);
}
}
loader.component.ts
import {Component, OnInit} from '@angular/core';
import {LoaderService} from './loader.service';
@Component({
selector: 'app-loader',
templateUrl: 'loader.component.html',
providers: [LoaderService]
})
export class LoaderComponent implements OnInit {
isLoading: boolean;
constructor(private loaderService: LoaderService) {
}
ngOnInit() {
this.loaderService.status.subscribe((val: boolean) => {
this.isLoading = val; // <--- Important Block
});
}
submitData() {
this.loader.display(true); // <--- Loader true,BehaviorSubject True.
this.http
.post("http://localhost:3000/login", this.loginForm.value).then(data => {
this.loader.display(false);
})
.catch(err => {
console.log(err);
this.loader.display(false); // <--- Loader Flase,BehaviorSubject False.
});
this.loader.display(false);
}
}
loader.component.html
<div class="loader" *ngIf="isLoading"></div>
It worked for me as well as many angular developers use BehaviorSubject this way.I hope it will help you.
Upvotes: 1
Reputation: 31115
From Promise.prototype.then()
docs:
If one or both arguments are omitted or are provided non-functions, then
then
will be missing the handler(s), but will not generate any errors.
Try passing an argument to the then
callback function.
this.authService.signInWithEmailAndPassword(
signInInfo.email,
signInInfo.password,
)
.then((response) => { // <-- `response` argument
this.isLoadingInProgress = false;
})
.catch(error => {
this.snackBarService.showSnackBar(error.message);
this.isLoadingInProgress = false;
});
Upvotes: 0