Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Create a mutable object starting from the state of a bloc. #4209

Open
MattiaPispisa opened this issue Jul 21, 2024 · 6 comments
Open
Labels
needs repro info The issue is missing a reproduction sample and/or steps question Further information is requested waiting for response Waiting for follow up

Comments

@MattiaPispisa
Copy link

Description

A use case I encounter in some situations (especially when creating complex forms) is having an object that changes over time but should not reside in the bloc state. For example, I have a TextFormField that require using a TextEditingController because their content can change due to actions outside the field itself. Recreating the TextEditingController would necessitate repositioning the cursor correctly and dealing with other issues.

A concrete example:
I have a bloc BlocA that manages the insertion and modification of a field T. In the UI, I have a TextFormField where I need to enter the field T, and with each change, a change event is triggered to BlocA. In addition to this field, to speed up the user experience, a QR code scanner can be used. So, values can be scanned using the camera. Upon scanning a value, a modification event is triggered to BlocA. Of course, the TextFormField must update with the new value obtained from the scan. And in any case, whether the insertion is through a QR code scan or because the user has modified a part of the content (not necessarily the end), the TextEditingController cursor must be positioned correctly.

Desired Solution

The idea is to create a widget similar to BlocSelector. Essentially, it involves listening to the state changes of the bloc, but in this case, to create and subsequently mutate an object (MutableState) looking at the previous.MutableState and the current bloc state. This object will then be passed as a parameter in the builder method to compose the child widget.

#4207

Alternatives Considered

Taking as an example the use of a TextFormField with a TextEditingController, the alternative solutions I have considered are:

  • Using a BlocSelector to get the value from the bloc and insert it into a TextEditingController. However, this implies that the controller is rebuilt with every change, requiring logic to correctly reposition the cursor based on where it was previously (which I cannot determine since the selector does not have the previous state value). In the previous example, how could I determine if the value was changed through a QR code scan (where I would want the cursor at the end of the text) or if the user positioned the cursor in the middle of the text and changed a character (in which case the cursor should remain after the newly entered character)?

  • Moving the controller into the bloc, but this would mean having a mutable state.

@felangel
Copy link
Owner

Hi @MattiaPispisa 👋
Thanks for opening an issue!

Can you share a minimal reproduction sample to illustrate the problem? Also, have you taken a look at some of the form validation examples? (https://github.com/felangel/bloc/blob/master/examples/flutter_form_validation/lib/main.dart)

@felangel felangel added question Further information is requested waiting for response Waiting for follow up needs repro info The issue is missing a reproduction sample and/or steps labels Jul 21, 2024
@MattiaPispisa
Copy link
Author

Yes, I am familiar with the examples, but unfortunately, they not address my specific case: the value of the TextFormField being modified by another field. This problem could also occur when needing to use ValueNotifier or other entities that have an internal state to update, rather than recreating them every time.

Starting from the example you linked, I will create a sample to illustrate my need.

@felangel
Copy link
Owner

Yes, I am familiar with the examples, but unfortunately, they not address my specific case: the value of the TextFormField being modified by another field. This problem could also occur when needing to use ValueNotifier or other entities that have an internal state to update, rather than recreating them every time.

Starting from the example you linked, I will create a sample to illustrate my need.

Thanks! Having a concrete example to look at would be super helpful 👍

@MattiaPispisa
Copy link
Author

MattiaPispisa commented Jul 21, 2024

Here I am :) !

My concrete example

This idea originated from this problem, and it can apply to various cases (like for ValueNotifier).

The example is very similar to the linked one, but here there is only one text field for the client, which can also be modified by external actions like the button below (imagine it as the QR code reader I mentioned before).

ClientInput is the equivalent input similar to those in the sample, with the issue that it won't update when the button is pressed.
ClientInputV2 represents one of the "Alternatives Considered" that I included in this issue, but here the problem shifts to managing the input cursor, try changing some characters in the middle of the input (Instead of the controller, using a key in the widget can also be considered, but the problem remains the same).

@MattiaPispisa
Copy link
Author

Hi @felangel, have you had time to look at the concrete example I linked and the idea I proposed?

@felangel
Copy link
Owner

Hi @felangel, have you had time to look at the concrete example I linked and the idea I proposed?

Sorry this slipped through the cracks! I'll take a look asap 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs repro info The issue is missing a reproduction sample and/or steps question Further information is requested waiting for response Waiting for follow up
Projects
None yet
Development

No branches or pull requests

2 participants