Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make an input observable?

Tags:

angular

I have a component with a few inputs that I'd like to be notified when it changes. I currently have it working by implementing ngOnChanges and figuring out which input was changed. However, I would prefer set my input declaration to @Input('select-values') selectValues:Observable<any>. This would allow me to subscribe to any new changes that occur in a much cleaner fashion.

ngOnInit() {     this.selectValues.subscribe(() => console.log('yay!')); } 

Issue with this is that I'm getting exception TypeError: this.selectValues.subscribe is not a function.

Just found out that this also works – Component Interaction. Intercept input property changes with a setter.

like image 299
self. Avatar asked Apr 08 '16 12:04

self.


People also ask

How many ways we can create observable in Angular?

In Angular we can subscribe to an observable in two ways: Manner 1: We subscribe to an observable in our template using the async pipe. The benefit of this is that Angular deals with your subscription during the lifecycle of a component.

What is the use of observable?

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 are observable returns?

Subscriptions to observables are quite similar to calling a function. But where observables are different is in their ability to return multiple values called streams (a stream is a sequence of data over time). Observables not only able to return a value synchronously, but also asynchronously.


2 Answers

You can wrap them in a form and listen to changes

this.myForm = fb.group({     'sku':  ['', Validators.required]   });  this.sku = this.myForm.controls['sku'];  this.sku.valueChanges.subscribe(     (value: string) => {       console.log('sku changed to: ', value);     } );  this.myForm.valueChanges.subscribe(     (value: string) => {       console.log('form changed to: ', value);     } ); 

http://blog.ng-book.com/the-ultimate-guide-to-forms-in-angular-2/

or

@Component({    ...,    template: '<input (change)="onChange($event.target.value)">' }) class MyComponent {   this.inputChange =new Subject();    onChange(e) {     this.inputChange.next(e);   } } 

See also this issue open https://github.com/angular/angular/issues/4062

like image 61
Günter Zöchbauer Avatar answered Oct 03 '22 19:10

Günter Zöchbauer


In fact, it's not possible to directly register against observables associated with events for DOM elements. You need to reference a DOM element directly and use then the fromEvent method of Observable.

Here is a sample:

@Component({   (...)   template: `     <input #input />   ` }) export class SomeComponent {   @ViewChild('input')   input:ElementRef;    ngAfterViewInit() {     var eventObservable = Observable.fromEvent(               this.input.nativeElement, 'keyup');   } } 

This issue could interest you as well:

  • https://github.com/angular/angular/issues/4062

That said you can leverage form controls to be notified when input value is updated. The valueChanges attribute of the control could be passed as input of the sub component.

@Component({   (...)   template: `     <input [ngFormControl]='ctrl'/>     <child-component [select-values]="ctrl.valueChanges"></child-component>   ` }) export class SomeComponent {   constructor() {     this.ctrl = new Control();      this.ctrl.valueChanges.subscribe(...);   } } 
like image 29
Thierry Templier Avatar answered Oct 03 '22 20:10

Thierry Templier