Reputation: 541
Id like to create a reuseable button component which can enable a spinner when clicked and disable the spinner when the function ends.
I have tried with an eventEmitter from the button component. But then the button doesnt know when the function it has called ends and so it doesnt know when to stop the spinner.
I have tried to take the function it should call as an input but then all the funcctions I need to call will have to be exported where they are binded to the instance they are on.
Cant I somehow hook into the (click)="doStuff()" and start the spinner before the doStuff is called and hide the spinner when doStuff ends =)
I have made this example to show what Im looking for https://stackblitz.com/edit/angular-generalbutton-handlingspinner?file=app/app.component.html
I look forward to see what you can think up =)
Upvotes: 1
Views: 873
Reputation: 877
What you can do is create a service which will have show and hide boolean property as observable. Then you can create reusable component which has button and spinner. Then in that component you can import service and call show and hide whenever you want and also subscribe to that service and attach show and hide boolean value to your spinner.
UPDATE :
You can do spinner show and hide after method end using @Input. Pass function you want to execute to your reusable button component and execute that function in button component. And after execution stop the spinner. As method is executing inside button component it waits till your async operation gets completed and then stops spinner.
progress-spinner.service.ts
export class ProgressSpinnerService {
constructor() { }
private loaderSource = new Subject<ProgressSpinnerState>();
// Observable string streams
loaderStateChanged$ = this.loaderSource.asObservable();
show() {
this.loaderSource.next(<ProgressSpinnerState>{ show: true });
}
hide() {
this.loaderSource.next(<ProgressSpinnerState>{ show: false });
}
}
progress-spinner.component.ts
export class ProgressSpinnerComponent implements OnInit {
@Input() onClickFunction : any;
show: boolean = false;
private subscription: Subscription;
constructor(
private loaderService: ProgressSpinnerService
) {
this.subscription = loaderService.loaderStateChanged$
.subscribe((state: ProgressSpinnerState) => {
this.show = state.show;
});
}
async startLoader(){
this.loaderService.show();
console.log("1 - The fire method on the button has started and the spinner is shown");
await this.onClickFunction();
console.log("4 - Now the fire method is done and the spinner is told to stop");
this.loaderService.hide();
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
progress-spinner.component.html
<button (click)="startLoader()">Start Loader</button>
<div *ngIf="show">
<div>
<mat-progress-spinner>
</mat-progress-spinner>
<br />
<div>Please wait....</div>
</div>
</div>
You can refer below
Upvotes: 2