flutter_command icon indicating copy to clipboard operation
flutter_command copied to clipboard

[Discussion] Piping commands

Open Abhilash-Chandran opened this issue 5 years ago • 7 comments

Hi Thomas,

While working on the Objective Key Roles demo I posted in twitter I came across a case of reloading the screen with all the objectives from the backend whenever a new objective is added, updated, deleted or canceling the edit of an objective. Thi primarily arises because of my choice of using shared preference as backend. I could have made the respective UI widget's react but I felt this need not be a ui logic.

example commands

Command<Objective, bool> addObjectiveCommand;
Command<Objective, bool> updateObjectiveCommand;
Command<Objective, bool> deleteObjectiveCommand;

Command to reload objectives

Command<void, List<Objective>> loadAllObjectivesCommand;

So I tried the prescribed command.listen approach from documentation. However this didn't work because all my commands were returning bool value as shown below and this didn't change as most of CRUD operations were successful (valueNotifier notifies only when the value changes). i.e

addObjectiveCommand.debounce(Duration(milliseconds: 32)).listen(
      (_, __) {
        print('Inside Listener for addObjective command');
        loadAllObjectivesCommand.execute();
      },
    );

What did work was manually calling the loadAllObjectiveCommand() inside the functional logic of addObjectiveCommand. It took me some time to understand why this worked and the above option didn't work. 🤦

Then I thought about adding an extension to the Command class that adds pipeCommand function which will call the the pipedCommand provided despite whether result changed or not as shown below.

extension on Command {
  // ignore: unused_element
  Command pipeCommand<TParam>(Command pipedCommand,
      {TParam pipedCommandParam,
      int debounceInMilliSeconds = 0,
      bool restrictCallBackOnError = true}) {
    this
        .results
        .debounce(Duration(milliseconds: debounceInMilliSeconds))
        .listen(
      (result, subscription) {
        if (!result.hasError || !restrictCallBackOnError) {
          print('Param inside pipe is $pipedCommandParam');
          if (result.hasData) {
            if (pipedCommandParam != null) {
              pipedCommand(pipedCommandParam);
            } else {
              pipedCommand();
            }
          }
        }
      },
    );
    return this;
  }
}

The above extension allows to pipe commands to call one after the other as shown below. I would like to know if this is a valid use or am I missing some thing here. 😄 🤔

Usage of extension

addObjectiveCommand.pipeCommand(loadAllObjectivesCommand)

PS: Maybe you should activate discussions for this repo. Then I can move this there 😄 .

Abhilash-Chandran avatar Jan 04 '21 15:01 Abhilash-Chandran

Ah, interesting point, I hadn't thought about that that command doesn't call notify when the value doesn't change. I think this is actually more like a bug because not only to queue commands this can be a problem.

I propose we add that we call notfify in case the value is the same and add a parameter to the command creation functions that allows you do disable this behavior.

Nethertheless we should also add a pipeResult or something like that to the Command Class itsef as its not unusual tho do that. When the not calling behavior is fixed you could in your case then use the´merge´function from funcional_listener

escamoteur avatar Jan 05 '21 14:01 escamoteur

Do you want to make a PR? :-)

escamoteur avatar Jan 05 '21 14:01 escamoteur

Sure.. I will give it a try.. 💯 😃

Abhilash-Chandran avatar Jan 05 '21 20:01 Abhilash-Chandran

How is this one coming along? It seems important. Currently I use a couple functional_listeners to transform data from a command into data that a certain part of the UI can understand.

It would be better if one command could depend on the outcome of another command. This way the transformed commands can also transmit the the other nice parts of command (other than the data/result). The listeners on the transformed data can also handle a "loading" and "error" states.

formvoltron avatar Feb 27 '21 23:02 formvoltron

As PR is in. Waiting for review 🧐

Abhilash-Chandran avatar Feb 27 '21 23:02 Abhilash-Chandran

hi, any updates on this?

geiziry avatar Aug 03 '21 20:08 geiziry

Hi, sorry for the long time to respond for me, but I had to struggle with my mental health for the last 7 months.

@Abhilash-Chandran and I will try to finish this soon

escamoteur avatar Feb 04 '22 17:02 escamoteur