3

I'm trying to find confirmation if I should prefer to use .forEach instead of .subscribe when I want to listen in on Angular's FormControl.valueChanges observable. FormControl API

In Angular's Documentation for forms they use .forEach without really explaining why and say you don't really need to understand it. Document Link

I also know from this answer that .forEach will bundle a sort of finite duration of events/incoming values into a promise.

So I tried to test both .forEach and .subscribe myself thinking that .forEach will be more performant in bundling keyboard input events if the user were to type monkey crazy on it.

constructor(private fb: FormBuilder) {
    this.createForm();
}
private createForm() {
    this.myForm = this.fb.group({
      name: '',
    });
}

private forEach = this.myForm.get('name').valueChanges.forEach(value => {
  console.log(value, 'forEach');
});

private subscription = this.myForm.get('name').valueChanges.subscribe(value => {
  console.log(value, 'subscribe');
});

In my test manually typing fast in the html input did not bundle .forEach values as I expected. Instead both .subscribe and .forEach emited values one character at a time.

Is there any benefit to .forEach over .subscribe in this situation and how can I create a test that can show the difference if there is a benefit to using .forEach over .subscribe?

Jonathan002
  • 9,639
  • 8
  • 37
  • 58

1 Answers1

4

Although it's often possible to use both of them you need to be aware that forEach works similarly to Promises that emit multiple values.

This also means you can't unsubscribe from forEach so with Observables that never complete you are very likely to create memory leaks (like valueChanges or Router events).

I'm not sure if valueChanges ever completes to be honest. I checked the source code at https://github.com/angular/angular/blob/5.0.0/packages/forms/src/model.ts#L636-L867 and they never send the complete notification. I didn't find any test that makes sure proper complete notification is sent (https://github.com/angular/angular/blob/5.0.x/packages/forms/test/form_control_spec.ts). So I don't know why they are using forEach in Angular docs. I think they should be using subscribe instead.

I don't even see why would valueChanges complete anyway. Only when you destroy the form but you don't control this yourself.

If you want to test anything you need to know what you expect as a result. I don't understand what benefits you want to see after writing tests.

martin
  • 93,354
  • 25
  • 191
  • 226
  • Thanks for this answer. Regarding the test, I also can't know yet what I want to test since I'm still trying to figure out if there was even a benefit in the first place. Your answer helped me decide to use `.subscribe` instead so I can have more control over the subscription. – Jonathan002 Nov 08 '17 at 14:05
  • I'll post and issue on Angular's github regarding using `forEach`. I'm really curious whether there's something I don't see and it's really better than `subscribe()` when using in combination with `valueChanges`. – martin Nov 08 '17 at 14:22
  • 1
    @martin, did you create the issue, can you please provide us the link, please? – Cristian Martinez Jun 22 '18 at 20:48