Reputation: 1574
I have a variable called loading
( and it's false
in the beginning and it is a boolean variable ) and a button which its text depend on that variable.
I wrote a method to do that for me like this:
changeBtnTxt() {
this.loginBtn = this.loading ? 'please wait':'login';
}
now, I want to know how can I watch that variable changing to fire this method using a RxJS
Observable.
this is my component
export class LoginFormComponentComponent implements OnInit {
loading = false;
loginBtn = 'ورود';
loginModel: LoginFormModel = new LoginFormModel();
@ViewChild('loginForm') form: any;
constructor(private service: LoginFormService,
private basicView: BasicViewService) {} // inject services to our component
ngOnInit() {}
login() {
this.loading = true;
this.changeBtnTxt(); // I want to remove this line and do the changes just by above code
this.service.loginModel = this.loginModel;
this.service.doLogin() // returns a Http get Observable
.subscribe(
res => {
},
msg => {
if (msg.status !== 401) {
this.loading = false; // want back to normal without call changeBtnTxt()
}
});
this.form.reset();
}
changeBtnTxt() {
this.loginBtn = this.loading ? 'ورود' : 'لطفا صبر کنید';
}
}
and here its html
<form novalidate #loginForm="ngForm" (submit)="login()">
<div class="ibox-title">
<h2 class="font-bold">ورود به حساب کاربری</h2>
</div>
<div class="ibox-content" style="padding-bottom: 15px;">
<div class="form-group">
<input type="text" class="form-control"
placeholder="نام کاربری"
name="username"
[(ngModel)]="loginModel.username"
required
#username="ngModel">
</div>
<div class="form-group" style="margin-bottom:0px">
<input type="password" class="form-control"
placeholder="رمزعبور"
name="password"
[(ngModel)]="loginModel.password"
required
#password="ngModel">
</div>
</div>
<div class="ibox-footer">
<input type="submit" class="btn btn-primary block full-width m-b"
[disabled]="loginForm.invalid || loading" [value]="loginBtn"/>
<button class="btn btn-sm btn-white btn-block" (click)="showHelp()">راهنما</button>
</div>
</form>
Upvotes: 5
Views: 19202
Reputation: 10303
You could use Subject and subscribe to the observable in the constructor... then add a simple function to emit the change with next... like this:
public myObservable = new Subject<boolean>();
constructor() {
this.myObservable.subscribe(val => {
this.loading = val;
this.loginBtn = 'loged in';
alert(this.loading)
})
}
changeBtnTxt() {
this.loginBtn = 'please wait';
setTimeout(() => { // Only for demonstration purpose
const val = (this.loading == true ? false : true);
this.myObservable.next(val);
}, 2000);
}
Check the working example in stakblitz
Upvotes: 5
Reputation: 2857
Here's an idea, you could use getter and setter methods and not have to use an observable at all:
private _loading: boolean = false;
public get loading(): boolean {
return this._loading;
}
public set loading(isLoading: boolean) {
this._loading = isLoading;
this.changeBtnTxt();
}
And then you just use loading
like a normal variable:
this.loading = true;
Upvotes: 1