Reputation: 1772
I have a simple css animation library that allows the display of an animation by calling loadService.animate(boolean);
but sadly it does not function anymore as I have been wrongly using an EventEmitter
in my service like such:
@Injectable()
export class LoadService {
@Output() animating: EventEmitter<any> = new EventEmitter();
constructor() {}
// User calls animate, we emit an event with the new boolean value
public animate(val: boolean) {
this.animating.emit(val);
}
getValue(): any {
return this.animating;
}
}
And subscribing to it in my component:
// Animation shown when animate == true
animate: boolean;
ngOnInit(): void {
this.loadService.getValue().subscribe((status: boolean) => {
// Events caught, we change the boolean to display the animation
this.animate = status;
});
this.handleShape();
}
But my subscription never catches anything, so I figured I wanted to create a custom Observable
in order to simply catch when a user calls animate
and consequently change the value of my boolean.
How may I define a custom observable in Angular2+? And how may I implement it in this scenario?
Upvotes: 1
Views: 1947
Reputation: 5889
In our service we create a BehaviorSubject
with default value of false
:
private _animate = BehaviorSubject(false);
get animate(): Observable<any>{
return this._animate.asObservable();
}
Also, in LoadService
, to update our observable
value:
toggleAnimation(value: boolean){
oldValue = this._animate.getValue();
this._animate.next(!oldValue);
}
Now in our component, you can subscribe to it like this:
constructor(private service: LoadService) {
this.service.animate.subscribe(state => {
// do stuff
console.log(state);
})
};
Upvotes: 4
Reputation: 1070
Angular team discourage the usage of eventemitter in a service, since it's used as an abstraction around a Subject. You can create an observable with custom logic by using the new keywork, and by providing the logic of the emission, or you can use a Subject, which is an observable and an observer, think of it as the most similar implementation of the observer pattern.
loadServiceSubject : Subject<any> = new Subject();
loadService$ : Observable<any> = loadServiceSubject.asObservable();
// other code
Think of the subject as a proxy between the event emitter and the listeners, anytime you call the next function on the subject, the emitted value will be pushed to all the subscribers of the observable.
// in client code
// suppose the service is injected in the constructor
this.animationService.loadService$.subscribe( this.doStuffOnNextCallback );
The "event" emitter just need to call the next, error or complete function on the subject itself.
// producer code, supposing it's also injected
this.animationService.loadServiceSubject.next(true);
Upvotes: 0