Reputation: 12025
I have declared the following variable:
public filter: IFilterWeekScheduleClassShort = {};
How to subscribe on changes(listen object filter)?
I tried this:
private filter: IFilterWeekScheduleClassShort = {};
private filterChanges: BehaviorSubject<IFilterWeekScheduleClassShort> = new BehaviorSubject(this.filter);
this.filterChanges.subscribe((model) => {
console.log(model);
});
Is it okay?
My final code:
public _filter: IFilterWeekScheduleClassShort = {};
private filterChanges: BehaviorSubject<IFilterWeekScheduleClassShort> = new BehaviorSubject(this._filter);
this.filter = {a: 1, b: 2}
set filter(value: any) {
this._filter = value;
this.filterChanges.next(this._filter);
}
get filter() {
return this.filterChanges.asObservable();
}
Subscribe on:
this.filter.subscribe(model => {
console.log(model);
});
Changes I make from form:
[(ngModel)]="_filter.teacherId"
Upvotes: 14
Views: 35345
Reputation: 96969
I think the closes that what you want to get is using scan()
:
const filterChanges$ = new Subject()
const defaultFilter = {}
const filter$ = filterChanges$
.pipe(
scan((acc, mergeFilter) => {
return {
...acc,
...mergeFilter,
}
}, defaultFilter)
)
filter$.subscribe(console.log);
filterChanges$.next({ name: 'abc' })
filterChanges$.next({ num: 42 })
filterChanges$.next({ name: 'xyz' })
Live demo: https://stackblitz.com/edit/rxjs6-demo-ngqkzv?file=index.ts
This will output:
{name: "abc"}
{name: "abc", num: 42}
{name: "xyz", num: 42}
Some time ago I made a small wrapper around window.Proxy
called rxjs-observable-object
that lets you wrap any object and then listen to changes on it (https://github.com/martinsik/rxjs-ds#object):
import { map } from 'rxjs/operators';
import { ObservableObject } from 'rxjs-observable-object';
const defaultFilter = {}
const { proxy, events } = new ObservableObject(defaultFilter);
const filter$ = events.onSet
.pipe(
map(({ target }) => target)
)
filter$.subscribe(console.log);
proxy['name'] = 'abc';
proxy['num'] = 42;
proxy['name'] = 'xyz';
Live demo: https://stackblitz.com/edit/rxjs6-demo-hojjkk?file=index.ts
However, rxjs-observable-object
is a little outdated now and requires rxjs-comapt
package installed as well.
The output for both examples is the same.
Upvotes: 2
Reputation:
Make a setter
private _filter: IFilterWeekScheduleClassShort = {};
set filter(value) {
this.doSomethingOnVariableChange(value);
this._filter = value;
}
Now you can use it like this
this.filter = 'x';
And your function doSomethingOnVariableChange
will be called with 'x'
.
With an observable :
private _filter: IFilterWeekScheduleClassShort = {};
private _filter$ = new BehaviorSubject(this._filter);
set filter(value) {
this._filter = value;
this._filter$.next(this._filter);
}
get filter() {
return this._filter$.asObservable();
}
Upvotes: 13