Reputation: 3775
I want to observe changes of a property with RxJS.
interface Test {
required: boolean;
toObserve: boolean;
}
class TestClass {
@Input() subject: Subject<Test>;
registerHandlers() {
this.subject.filter(element => element.required).subscribe(next =>
// Observe a property of every element that was registered
Observable.of(next.toObserve).subscribe(val => {
if (val) {
// DO SOMETHING
} else {
// DO SOMETHING ELSE
}
})
);
}
}
I got a subject into which newly created objects are pushed. Several components subscribe on these and should react on different property changes.
In the above example if toObserve
is set I want the component to do something. This works exactly once currently - Depending on the value the element has when it is registered with subject.next(element)
the correct path is executed.
However as soon as I change the value of element.toObserve
nothing is happening and the subscription seems to have no effect anymore.
Upvotes: 1
Views: 6482
Reputation: 896
I do this, in this example I used a attribute type number, but, you can use another like "Test"
import { Observable, Subject, ReplaySubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class CoinsService {
private total: Subject<number> = new ReplaySubject<number>(1); //This is my attribute
private total$ = this.total.asObservable(); //This is my observable
constructor() {
this.total.next(0); //Init my parameter
}
async add(coins: number) {
// I must subscribe for take the value of attribute
this.total$
.pipe(
take(1) // Guaranty that is the one time and release the subscription
)
.subscribe(async accumate => {
this.total.next(accumate + coins);// Set the new value
});
}
getTotal(): Observable<number> {
return this.total$;//Return this observable for client subscription on every change
}
}
That is.
I hope help you.
Upvotes: 0
Reputation: 1315
Doing a subscribe into a subscribe is not recommended. I would rather create an operators chain to your subject and subscribe to it:
If you want to perform some side effects in your components depending on a specific property in your stream, you can use the do operator:
interface Test {
required: boolean;
toObserve: boolean;
}
class TestClass implements OnInit {
@Input() subject: Subject<Test>;
ngOnInit() {
this.registerHandlers().subscribe();
}
registerHandlers() {
return this.subject
.filter(element => element.required)
.do(next => {
if (next.toObserve) {
// DO SOMETHING
} else {
// DO SOMETHING ELSE
}
});
}
}
Upvotes: 2
Reputation:
Sorry, but I reckon you didn't completely understand how subscription is to be done properly.
You have your subject
@Input() subject: Subject<Test>;
and you want to trigger actions whenever the subject changes. Then put this subscription into your ngOnInit()-method:
this.subject.subscribe(value => {
// and here goes your evaluation
if(value.toObserve) {
// do something
} else {
// do something else
}
});
and you can go even further and do something like this
this.subject.subscribe(value => {
// and here goes your evaluation
if(value.toObserve) {
// do something
} else {
// do something else
}
if(value.required) {
// do something
} else {
// do something else
}
});
Upvotes: 1