Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind to @Output Observable instead of callback?

Tags:

angular

rxjs

I have a slider component that emits numbers while you drag the slider, which is usable like so: <my-slider (change)="onSlide($event)"></my-slider>. I'd like to get rid of the onSlide method and instead bind the change event stream to an Observable<number> property (instead of a callback).

I am using an Angular 2 EventEmitter for my @Output. EventEmitter inherits from a RxJs Subject, which is an Observable and an Observer. I wish to reuse the Observable side of the EventEmitter.

Of course I can push values that enter through onSlide onto another Subject, but I wish to prevent this boilerplate and overhead. Is there a way?

like image 515
Lodewijk Bogaards Avatar asked Dec 31 '15 16:12

Lodewijk Bogaards


People also ask

Is event emitter an observable?

EventEmitter is used in the directives and components to emit custom events either synchronously or asynchronously. Since EventEmitter class extends RxJS subject class, this means it is observable and can be multicasted to many observers.

What is the use of @output in angular?

The @Output() 's type. Tells Angular to create a new event emitter and that the data it emits is of type string. For more information on EventEmitter , see the EventEmitter API documentation. The addNewItem() function uses the @Output() , newItemEvent , to raise an event with the value the user types into the <input> .

What is observable angular12?

Observables provide support for passing messages between parts of your application. They are used frequently in Angular and are a technique for event handling, asynchronous programming, and handling multiple values.

What is callback observable?

A callback function is a function passed into another function as an argument which is invoked inside the callee function(here greeting) to complete or after some kind of actions.


2 Answers

Not sure if relevant or if it helps someone: I ran into a similar issue: I wanted to consume a property of type Observable<number> provided by a component in the parent component.

After reading Observables and Reactive Programming in Angular 2, I noticed that I need to "turn" around my architecture and let the parent create the Observable and then assign it to the child.

So instead of having a MyComponent with an @Output() of type Observable<number> (which was then initialized to new BehaviorSubject(0) and modified using calls to next), I changed MyComponent to haven an @Input() of type BehaviorSubject<number>:

@Component({
  selector: 'my-component',
  template: `
    <button (click)="increment()">Click me!</button>
  `,
})
export class MyComponent {
  private _count : number = 0;

  @Input()
  public counter : BehaviorSubject<number>;

  public increment() {
    this._count++;

    if (this.counter)
      this.counter.next(this._count);
  }
}

The parent now creates a BehaviorSubject and binds to the property. It can easily consume the BehaviorSubject as an Observable:

@Component({
  selector: 'my-app',
  template: `
    <my-component [counter]="count"></my-component>
    <span>{{text | async}}</span>
  `,
})
export class App {
  public text : Observable<string>;

  public count : BehaviorSubject<number> = new BehaviorSubject(0);

  constructor() {
    this.text = this.count.map(n => "Click: " + n);
  }
}

Plunker: https://plnkr.co/edit/rKtVWmmGnFn4Po4B4CCL?p=preview

So in your case, I would say that your slider should provide an @Input (maybe call it value or number) and let the parent assign an observable (instead of letting the child create one).

like image 163
Matthias Avatar answered Oct 25 '22 21:10

Matthias


One of core difference between Angular 1 and Angular 2 is that change detection is always performed from top to bottom. That makes performance much better. Also there is no need to perform "stabilization" ($digest loop) as it was in Angular 1.

In Angular 2 you can't "push" change back in other way, except emitting event with EventEmitter/Subject, so Angular 2 can start checking component's Change Detectors.

Here is nice article about this topic.

like image 32
Valentyn Shybanov Avatar answered Oct 25 '22 23:10

Valentyn Shybanov