joanpablo / reactive_forms

This is a model-driven approach to handling form inputs and validations, heavily inspired in Angular's Reactive Forms
MIT License
469 stars 89 forks source link

Previous value of controller #237

Closed Solido closed 2 years ago

Solido commented 2 years ago

When accessing the stream of a valueChanges what is the best way to also access the value pre-update. My understanding is currently I need to handle this myself.

This is very useful as general use case but even more when dealing with FormArray.

Thank you !

joanpablo commented 2 years ago

Hi @Solido,

Thanks for the issue, but could you give me a use case to better understand your issue?

Solido commented 2 years ago

Yes in my case I load a form with previous saved data then I need to compare each event to decide of the logic. It is a fair large change in the API so no expectation here but mainly raise the case. Having Event<T,T> instead of . To currently solve that I have to copy the value in my widgets states replicating the info outside of a FormController. Values are compared and diffed to trigger the new value.

joanpablo commented 2 years ago

Hi @Solido,

An example would be very useful. Because if the event is triggered, then is because the value has changed. So I'm not sure if you want to manually check if the value actually changed or you are completely aware that the value changed and want to make some logic based on the previous value?

Do you want to know if the value really changed? Or do you just want to check some other logic?

joanpablo commented 2 years ago

Hi @Solido,

Have you tried to use pairwise function from rxdart.

I mean include rxdart in your project, import the rxdart library in the file you are working on, and use the pairwise function (this function is an extension to Streams) against the valueChanges from the controller.

This function gives you the previous and current value of a Strem. Please check if it is working and let me know as soon as possible. Your answer will let me know if you can work with Reactive Rorms and rxdart out of the box or if I need to include rxdart as a dependency to Reactive Forms and change all my Streams to Subjects

joanpablo commented 2 years ago

Hi again @Solido,

I have confirmed the use of rxdart with a simple test:

test('FormControl emits current and previous value', () {
      // Given: a control with default value
      const firstValue = 'Reactive';
      const lastValue = 'Forms';

      final formControl = FormControl<String>(value: '');

      // Expect: the control emits current and previous value
      expectLater(formControl.valueChanges.pairwise(), emits([firstValue, lastValue]));

      // When: change values
      formControl.value = firstValue;
      formControl.value = lastValue;
    });

So you can include rxdart in your project and use it with Reactive Forms and you will have your desired feature out of the box.

Solido commented 2 years ago

Hey @joanpablo

This is a fluent approach to the problematic. My main goal was to avoid having to handle the value in differents places, having to copy the already present model entry into a widget state field to diff later. Having a message in the form <T,T> simplify a lot specifically when there is a lot of entries.

I avoid rxdart has it can be opaque for debug but it this case it fit well.

Thanks for your intervention on the matter !

vasilich6107 commented 2 years ago

Hi @Solido I’m experimenting with a set of listener/builder/consumer approach(similar to bloc library pattern) https://pub.dev/packages/reactive_forms_lbc

Maybe you could find useful in your case