11

I have a reactive form, with a text input. For ease of access in my typescript, I declared:

get parentId(): FormControl {
    return this.addForm.get("parentId") as FormControl;
}

This part works, the control is properly accessed.

Now in my ngOnInit if I do this:

this.parentId.valueChanges.subscribe(() => console.log("Changed"));

The console log is executed at every character changed in the input, as expected. But if I do this:

this.parentId.valueChanges.pipe(tap(() => console.log("Changed")));

Nothing happens. No errors, no anything. I tried also using map, switchMap, etc.nothing works. It seems that the pipe does not work on valueChanges. I am using the pipe method elsewhere in my code on different observables without any problem.

And I need to use pipe here in order to debounce, map, etc.

Any idea what I'm doing wrong?

-- Edit --

This is the code example from Angular Material site, on Autocomplete component:

ngOnInit() {
   this.filteredOptions = this.myControl.valueChanges
       .pipe(
          startWith(''),
          map(val => this.filter(val))
       );
}

There is no subscribe at the end and the example works.

5
  • 6
    Observables won't emit anything until you subscribe to them. So if you want to see output from tap you need to call subscribe() after pipe(). Commented May 24, 2018 at 10:25
  • 2
    You need a subscribe() at the end of the chain to activate the observable. Commented May 24, 2018 at 10:26
  • 1
    In the example on Angular Material site on autocomplete component there is no such thing: Commented May 24, 2018 at 10:26
  • 1
    You're both right. There is no subscribe in the example because the pipe is bound to a variable which is "subscribed to" with the async pipe. My fault for not understanding that. Thanks. Commented May 24, 2018 at 10:32
  • @martin Just came here looking for the same problem, thanks very much! Commented May 31, 2018 at 16:37

1 Answer 1

26

You need to subscribe to activate the Observable,

ngOnInit() {
   this.filteredOptions = this.myControl.valueChanges
       .pipe(
          startWith(''),
          map(val => this.filter(val))
       ).subscribe();
}
Sign up to request clarification or add additional context in comments.

3 Comments

So simple, yet so accurate. Thanks. I'm still struggling to wrap my head around observables and their differences from promises.
You can use the pipe async at your template too. *ngFor="let option of filteredOptions | async"
Getting this error when add .subcription TS2740: Type 'Subscription' is missing the following properties from type 'Observable<string[]>': _isScalar, source, operator, lift, and 6 more. I assign like this filteredOptions: Observable<string[]>;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.