joanpablo / reactive_forms

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

Add 'markAsDirty' parameter to AbstractControl.updateValue() #278

Closed MBulli closed 2 years ago

MBulli commented 2 years ago

As far as I can tell calling updateValue() on a FormControl programmatically does not mark the control as dirty. It would be helpful if updateValue() had a bool parameter 'markAsDirty' which marks the control as dirty after updating the value.

My use case is a button where I want to reset the value of a ReactiveDropdownField with the following handler:

onClearPressed: form.control('status').value != null
    ? () {
        form.control('status').updateValue(null);
        form.control('status').markAsDirty();
      }
    : null,

If updateValue() had a parameter to set the control as dirty I could rewrite my code like that:

onClearPressed: form.control('status').value != null
    ? () => form.control('status').updateValue(null, markAsDirty: true)
    : null,

I use the dirty state to decide if I have to reload a list, thus, clearing a value needs to trigger a reload. The default value of the new parameter should be false to avoid a breaking change.

void updateValue(T? value, {bool updateParent = true, bool emitEvent = true, bool markAsDirty = false});
joanpablo commented 2 years ago

Hi @MBulli,

Thanks for using and supporting Reactive Forms.

The main reason for the dirty field is to know when the control has been updated through the UI (by the User) or programmatically. That is why by default the updateValue (you can also use control.value directly to assign a value to the control) does not change the dirty property, you need to explicitly call markAsDirty() method to mark the control as dirty (This is what all Reactive Widgets do behind scenes when the User changes values through the widgets).

As far as I understand from your comments you are using the dirty property to determine when to update a list or not. Could you give a more complete code example so we can find another approach, and instead of using the dirty property for business logic implementation maybe we can use something else?

It would be nice to have a better example of your use case

MBulli commented 2 years ago

Is it business logic? In my example I have a ReactiveDropdownField with a IconButton next to it to reset the dropdown field i.e. set the form control to null (that's the event handler in my first post).

It is part of a screen where you can configure a filter. When the user leaves this screen the list is told to reload itself if the user made changes. Tapping the clear button next to ReactiveDropdownField should count as user input as she is resetting the filter imho.

I will later post a complete code example.

joanpablo commented 2 years ago

Hi @MBulli,

I understand that in your specific use case it is nicer to have just 1 line of code:

form.control('status').updateValue(null, markAsDirty: true);

instead of 2 lines of code:

form.control('status').updateValue(null);
form.control('status').markAsDirty();

But what if somebody on the contrary wants to mark them as Pristine?

form.control('status').updateValue(null, markAsPristine: true);

And what about if somebody wants it to be touched?

form.control('status').updateValue(null, markAsTouched: true);

But, wait and if somebody wanted as untouched?

form.control('status').updateValue(null, markAsUntouched: true);

And what about the Focus?

form.control('status').updateValue(null, focused: true);

And remove the Focus?

form.control('status').updateValue(null, unfocused: true);

So there could be several use cases. How would you imagine the arguments of the updateValue method if you want to satisfy all the use cases?

MBulli commented 2 years ago

Hi @joanpablo,

sorry for not given a complete example but my focus at work was shifted away from flutter for now.

Yes, a one-liner is temping, given the lean arrow syntax dart allows for lambdas. Plus, I was kinda surprised that the updateValue() method does not mark the field as changed (dirty).

However, I got your point. If my feature request does not fit to the way you want to see your framework evolve I'm totally fine with it. In that case this issue can be closed.