Need a way to tell if a command has not yet started execution
According to the comment for CommandResult class:
/// Combined execution state of a `Command` represented using four of its fields.
/// A [CommandResult] will be issued for any state change of any of its fields
/// During normal command execution you will get this items by listening at the command's [.results] ValueListenable.
/// 1. If the command was just newly created you will get `param data, null, null, false` (paramData, data, error, isExecuting)
/// 2. When calling execute: `param data, null, null, true`
/// 3. When execution finishes: `param data, the result, null, false`
/// `param data` is the data that you pass as parameter when calling the command
In short, the way to tell whether a command has yet to execute or has completed execution is to see if result.data is null.
However, the actual implementation is inconsistent. The result.data always returns the initial value set on command creation before executing. If the command returns the same value after execution, there is no way to tell them apart. Ideally, CommandResult should have both a getter that returns the initial value before the actual data, as well as a getter that follows the comment to indicate a newly created command before execution.
Moreover, even when CommandResult were fixed to follow its comments, for commands that have no return value, there is still no way to tell if execution has yet started, as the result.data will always be null before and after the execution.
I know I can use another field to track that info, but it's not an elegant solution. The Command class should embed that state internally, just like in FutureBuilder you can use snapshot.connectionState to differentiate ConnectionState.none against ConnectionState.done.
Hmm, I am honestly surprised, why you would need that information. You mean you can't differentiate if the value is the initial value or the result of a previous call? When a command start executing, "isExecuting" get immediately true. How would you then differentiate if the command has not executed at all or if it was executed before? That would need a resetCommandState function then or something like that.
I am not against an improvement but I need to get a better understanding when you would need that information. Typically such more detailed state information is stored in the class containing the command.
Am 8. März 2025, 08:45 +0100 schrieb Ming Jiang @.***>:
According to the comment for CommandResult class:
/// Combined execution state of a
Commandrepresented using four of its fields. /// A [CommandResult] will be issued for any state change of any of its fields /// During normal command execution you will get this items by listening at the command's [.results] ValueListenable. /// 1. If the command was just newly created you will getparam data, null, null, false(paramData, data, error, isExecuting) /// 2. When calling execute:param data, null, null, true/// 3. When execution finishes:param data, the result, null, false///param datais the data that you pass as parameter when calling the command In short, the way to tell whether a command has yet to execute or has completed execution is to see if result.data is null. However, the actual implementation is inconsistent. The result.data always returns the initial value set on command creation before executing. If the command returns the same value after execution, there is no way to tell them apart. Ideally, CommandResult should have both a getter that returns the initial value before the actual data, as well as a getter that follows the comment to indicate a newly created command before execution. Moreover, even when CommandResult were fixed to follow its comments, for commands that have no return value, there is still no way to tell if execution has yet started, as the result.data will always be null before and after the execution. I know I can use another field to track that info, but it's not an elegant solution. The Command class should embed that state internally, just like in FutureBuilder you can use snapshot.connectionState to differentiate ConnectionState.none against ConnectionState.done. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.> minkyn created an issue (escamoteur/flutter_command#22) According to the comment for CommandResult class: /// Combined execution state of aCommandrepresented using four of its fields. /// A [CommandResult] will be issued for any state change of any of its fields /// During normal command execution you will get this items by listening at the command's [.results] ValueListenable. /// 1. If the command was just newly created you will getparam data, null, null, false(paramData, data, error, isExecuting) /// 2. When calling execute:param data, null, null, true/// 3. When execution finishes:param data, the result, null, false///param datais the data that you pass as parameter when calling the command In short, the way to tell whether a command has yet to execute or has completed execution is to see if result.data is null. However, the actual implementation is inconsistent. The result.data always returns the initial value set on command creation before executing. If the command returns the same value after execution, there is no way to tell them apart. Ideally, CommandResult should have both a getter that returns the initial value before the actual data, as well as a getter that follows the comment to indicate a newly created command before execution. Moreover, even when CommandResult were fixed to follow its comments, for commands that have no return value, there is still no way to tell if execution has yet started, as the result.data will always be null before and after the execution. I know I can use another field to track that info, but it's not an elegant solution. The Command class should embed that state internally, just like in FutureBuilder you can use snapshot.connectionState to differentiate ConnectionState.none against ConnectionState.done. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.>
Two reasons I would like that feature:
-
I am trying to refactor my code from using
FutureBuilderto the command pattern, where instead of listening to the command, I was listening to the returned future result of the command function. Without the feature, there is no easy way to correspond toConnectionState.nonecase. -
The official flutter sample repo compass_app demonstrates a lot on command design pattern. Some examples include
loadfrom home_viewmodel, andsearchfrom results_viewmodel, where those commands are async initialization the ViewModel needs to perform on construction. In the widget code, the UI will show something before search completes, and a progress indicator when the command is running, and finally something else after search completes or when error happens. In other words, UI will display differently forready,running,completedanderror.
I think implementation wise, it should suffice to just add a completed field, like what the official sample does. This way I can tell if the command has yet to execute by !completed && !isExecuting. And I feel that onSuccess in CommandBuilder would be more useful if it also implies the completion status.
Also, being able to reset the command state would be nice, but not necessary for me. All I need is to tell when the command hasn't executed at all. If it's executed before, and will be executed again, my UI is fine with displaying the previous results first.
So, my expected completed field will start with false, and turns into true after execution regardless of errors, and stays true until the command becomes isExecuting for the next run where it turns into false again, and finally becomes true after the second run.
First of all, are you aware, that I did full refactoring of the compass app using flutter_command and watch_it?
https://github.com/escamoteur/compass_fork
Normally I don't need the done state because I listen to the command itself or use a CommandBuilder. And receiving a CommandResult with hasData=true means success.
Especially when you refer to an additional "ready State" this gets difficult because when will it be ready after success?
The underlying difference to a Future is that Futures are one time use objects Am 8. März 2025, 18:40 +0100 schrieb Ming Jiang @.***>:
Two reasons I would like that feature:
I am trying to refactor my code from using FutureBuilder to the command pattern, where instead of listening to the command, I was listening to the returned future result of the command function. Without the feature, there is no easy way to correspond to ConnectionState.none case.
- The official flutter sample repo compass_app demonstrates a lot on command design pattern. Some examples include load from home_viewmodel, and search from results_viewmodel, where those commands are async initialization the ViewModel needs to perform on construction. In the widget code, the UI will show something before search completes, and a progress indicator when the command is running, and finally something else after search completes or when error happens. In other words, UI will display differently for ready, running, completed and error.
I think implementation wise, it should suffice to just add a completed field, like what the official sample does. And I feel that onSuccess in CommandBuilder would be more useful if it also implies the completion status. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***> minkyn left a comment (escamoteur/flutter_command#22) Two reasons I would like that feature:
- I am trying to refactor my code from using FutureBuilder to the command pattern, where instead of listening to the command, I was listening to the returned future result of the command function. Without the feature, there is no easy way to correspond to ConnectionState.none case.
- The official flutter sample repo compass_app demonstrates a lot on command design pattern. Some examples include load from home_viewmodel, and search from results_viewmodel, where those commands are async initialization the ViewModel needs to perform on construction. In the widget code, the UI will show something before search completes, and a progress indicator when the command is running, and finally something else after search completes or when error happens. In other words, UI will display differently for ready, running, completed and error.
I think implementation wise, it should suffice to just add a completed field, like what the official sample does. And I feel that onSuccess in CommandBuilder would be more useful if it also implies the completion status. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
Wow, I didn't know your refactoring work. That looks pretty cool. I will definitely take a look.
Now I understand your concern is on the following runs of the command after the first execution. Again, as I mentioned above, in my case I deal mostly with just one-time init async command, where I only care about the very first unstarted state.
Why not just defining the Command with a nullable return type and pass null as initial value?
Thing is storing if a Command has already run can be easily done by yourself as that is more a state of your business logic than of command itself.
BTW I have to apologize, I just realized that the Readme of the package needs some updating Am 8. März 2025, 18:48 +0100 schrieb Ming Jiang @.***>:
Also, being able to reset the command state would be nice, but not necessary for me. All I need is to tell when the command hasn't executed at all. If it's executed before, and will be executed again, my UI is fine with displaying the previous results first.
So, my expected completed field will start with false, and turns into true after execution regardless of errors, and stays true until the command becomes isExecuting for the next run where it turns into false again, and finally becomes true after the second run.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
minkyn left a comment (escamoteur/flutter_command#22) Also, being able to reset the command state would be nice, but not necessary for me. All I need is to tell when the command hasn't executed at all. If it's executed before, and will be executed again, my UI is fine with displaying the previous results first. So, my expected completed field will start with false, and turns into true after execution regardless of errors, and stays true until the command becomes isExecuting for the next run where it turns into false again, and finally becomes true after the second run. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
If you are only doing onetime calls, maybe instead of commands just use watch_it with it's watchFuture function? Am 8. März 2025, 18:56 +0100 schrieb Ming Jiang @.***>:
Wow, I didn't know your refactoring work. That looks pretty cool. I will definitely take a look.
Now I understand your concern is on the following runs of the command after the first execution. Again, as I mentioned above, in my case I deal mostly with just one-time init async command, where I only care about the very first unstarted state.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
minkyn left a comment (escamoteur/flutter_command#22) Wow, I didn't know your refactoring work. That looks pretty cool. I will definitely take a look. Now I understand your concern is on the following runs of the command after the first execution. Again, as I mentioned above, in my case I deal mostly with just one-time init async command, where I only care about the very first unstarted state. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
Storing a null initial value won't work when my command has no return type.
Yes, that's exactly what I was going to do by adding a listening callback, or use your watch_it package, before posting the question here to find any luck ;-)
If you don't need a return type, then why not use a bool return type and return true on success? Many ways to reach the same goal. Am 8. März 2025, 19:10 +0100 schrieb Ming Jiang @.***>:
Storing a null initial value won't work when my command has no return type.
Yes, that's exactly what I was going to do by adding a listening callback, or use your watch_it package, before posting the question here to find any luck ;-)
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
minkyn left a comment (escamoteur/flutter_command#22) Storing a null initial value won't work when my command has no return type. Yes, that's exactly what I was going to do by adding a listening callback, or use your watch_it package, before posting the question here to find any luck ;-) — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
I know those are all viable solutions, but not elegant from my perspective. I guess I was just used to what FutureBuilder offers and thought the states could possibly match.
As said, a Future is just different to the concept of a Command. But I will think if I add more states to the CommandResult Am 8. März 2025, 19:19 +0100 schrieb Ming Jiang @.***>:
I know those are all viable solutions, but not elegant from my perspective. I guess I was just used to what FutureBuilder offers and thought the states could possibly match.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
minkyn left a comment (escamoteur/flutter_command#22) I know those are all viable solutions, but not elegant from my perspective. I guess I was just used to what FutureBuilder offers and thought the states could possibly match. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
Kamino closed and cloned this issue to flutter-it/command_it