8 Replies Latest reply on Sep 6, 2011 6:55 AM by Chris Velevitch

    Looking for examples of command chaining in Parsley 2.4

    Chris Velevitch Level 1

      In order to help me understand, I'm looking for examples of command  chaining in Parsley. What I mean by command chaining is when one command  returns a result that is then immediately used to initiate another  command. I ask this question here because the parsley forums have been  down for 2 days.

        • 1. Re: Looking for examples of command chaining in Parsley 2.4
          Claudiu Ursica Level 4

          Actually the parsley forum has bee down for more than 2 weeks...

          Look into the task utility that comes with parsley, it can do both sequence and parallel/concurrent tasks ...

           

          C

          • 2. Re: Looking for examples of command chaining in Parsley 2.4
            Chris Velevitch Level 1

            I have tried the Task framework, but the examples are poor  because there are no examples showing how to the Task Framework with the  Parsley Framework. I keep getting "value is not a function" when I try  using messaging and dynamic commands.

            • 3. Re: Looking for examples of command chaining in Parsley 2.4
              Claudiu Ursica Level 4

              What is your task at hand?

              I remember using it to load data at app start, had a task group inside a command inject the tasks into the commands and assign them to the group, at execute just let the task group do its magic. Show some details, code I will probable be able to help ...

               

              C

              • 4. Re: Looking for examples of command chaining in Parsley 2.4
                Chris Velevitch Level 1

                Firstly, I've done the inverse of what you have done. I created a task per command and each task dispatches the message for the command and wait for the results. Then I've created a sequential task group and added each task and then start the group. Here is an example of one of my tasks:-

                 

                package mytasks
                {
                    import org.spicefactory.lib.task.Task;
                    import org.spicefactory.parsley.asconfig.ActionScriptContextBuilder;
                   
                    import MyMessage;
                    import MyModel;
                   
                    public class MyTask extends Task
                    {
                        [Inject(id="myModel")] [Bindable]
                        public var myModel:MyModel;
                       
                        [MessageDispatcher]
                        public var messageDispatcher:Function;
                       
                        public function MyTask()
                        {
                            super();
                            ActionScriptContextBuilder.build(MyConfig);
                        }
                       
                        protected override function doStart():void {
                            messageDispatcher(new MyMessage());   
                        }


                        [MessageHandler]
                        public function handleMyMessage(message:MyMessage):void {
                            if (message.success == true) {
                                myModel.debug = "success";
                                complete();
                            } else {
                                error("my task failed");
                            }
                        }
                       
                    }
                }

                 

                And my configuration file contains:-

                 

                <model:MyModel id="myModel"/>
                <spicefactory:DynamicCommand type="{MyCommand}" selector="execute" result="handleResult" error="handleError"/>

                 

                My command is:-

                 

                package mycommands
                {
                    import mx.controls.Alert;
                    import mx.collections.ArrayCollection;
                    import mx.rpc.AsyncToken;
                    import mx.rpc.events.FaultEvent;
                    import mx.rpc.events.ResultEvent;
                    import mx.rpc.remoting.RemoteObject;
                   
                    import MyMessage;
                    import MyModel;
                   
                    public class MyCommand {
                       
                        [Inject(id="ro")]
                        public var service:RemoteObject;
                       
                        [Inject(id="myModel")]
                        public var myModel:MyModel;


                        public function execute (message:MyMessage) : AsyncToken {
                            return service.getRemoteData(myModel.id);
                        }


                        public function handleResult(result:ResultEvent, message:MyMessage):void {
                            if (result.result != null) {
                                myModel.dataCollection = result.result as ArrayCollection;
                                message.success = true;
                            }
                        }
                       
                        public function handleError(fault:FaultEvent, trigger:MyMessage):void {
                            Alert.show(fault.toString());
                        }
                    }
                }

                • 5. Re: Looking for examples of command chaining in Parsley 2.4
                  Claudiu Ursica Level 4

                  Why are you building the context in the task constructor?

                   

                  I don't see the code which is starting your task but aside from that it should work if your context is properly configured and finished creating by the time you dispatch your event/message.

                   

                  However unless I am missing something you are reacting to the same to the same event in both task and command:

                   

                          public function handleMyMessage(message:MyMessage):void {

                              if (message.success == true) {

                                  myModel.debug = "success";

                                  complete();

                              } else {

                                  error("my task failed");

                              }

                          }

                   

                   

                  public function execute (message:MyMessage) : AsyncToken {

                              return service.getRemoteData(myModel.id);

                          }

                   

                  Your task should be notified by the command that it finished execution. Which I don't see in your code happening. You can dispatch a managed event from task to the command but for some reason I see a bad smell attached to it ... Other option might include command update some bindable property on the model and task watch it... Though it seems your are going into lots of trouble for nothing...

                   

                  I think it should be the other way around...

                   

                  This is from the docs:

                   

                  Supported Command Types

                  The preceding examples all showed commands that execute remote calls and return an AsyncToken. This is not the only option available though. The command feature

                  can also be used with Cinnamon Remoting, which returns instances of ServiceRequest instead as it does not use Flex RemoteObjects. Finally the commands are integrated with

                  the Spicelib Task Framework, so a command can also declare Task as the return

                  type.

                   

                  Have a command which returns tasks or taskgroups. Is it a reason why you choose to go the other way around?

                   

                  The error you mentioned above has to do with configuration usually. Maybe this link helps:

                   

                  http://www.techpages.org/parsley-and-cairngorm-framework/flex-parsleycairngorm-framework-i njection-problems/978/

                   

                  C

                  • 6. Re: Looking for examples of command chaining in Parsley 2.4
                    Chris Velevitch Level 1

                    I'm building the context in theTask constructor because the Task Framework was not written as MXML tags, so in order to use the Parsley messaging to initiate commands, I need to initialise the parsley context. (see http://blog.mattes-groeger.de/actionscript/context-aware-tasks/). Unfortunately,  Mattes left out the definition of the IContextProvider interface so I can't use his code.

                     

                    Since I'm using the Task framework, my task is started with code like:-

                                    var sequentialTasks:TaskGroup = new SequentialTaskGroup("start tasks");
                                   
                                    sequentialTasks.addTask(new MyTask());
                                    sequentialTasks.addTask(new MyNextTask());
                                    sequentialTasks.addTask(new MyFinalTask());
                                    sequentialTasks.start();

                    Maybe my code (and examples) are poorly conceived.

                     

                    My intent is that a task uses Parsley messaging to run a command and waits for the command to finish before declaring the task complete. I'm using the using the MessageDispatcher metatag to declare the message dispatcher, the MessageHander metatag to declare the function to call when the command has successfully completed and the MessageError metatag to declare the function to call when the command failed. And in the command class, because it's using RemoteObject, I've declared the RemoteObject result and error functions to update the message with command status for use by the MessageHandler or MessageError functions in the task body. Then, depending on the result of the command I call the tasks complete or error functions.

                     

                    But since I haven't been able to successfully initialise the Parsley context, I getting:-

                    value is not a function

                    error during execution.

                    • 7. Re: Looking for examples of command chaining in Parsley 2.4
                      Claudiu Ursica Level 4

                      Unless your are omitting code or I am blind I don;t see the part where your task is not managed so a call to dispatch message will give you the error because the function has not been decorated with the , but if you have the task managed is like having 2 commands... I still don't see the big need for the task framework in there, but that is a different topic. 

                       

                      You need some hookup code like this to make the task context aware:

                       

                      _dynamicObject = IContextProvider(parent)

                                  .context.addDynamicObject(this);

                       

                      As it is stated there the context is available from the parent. So basically when a new task is created it becomes managed by being added to the context. you only build a context with the actionscript builder. But your context is not aware of the task's existence because nobody informs the context about the task.

                       

                      If I may suggest have a dynamic command and create the tasks on the fly once the task are finished the dynamic command vanishes and you're done.

                       

                      C

                      • 8. Re: Looking for examples of command chaining in Parsley 2.4
                        Chris Velevitch Level 1

                        Firstly, I haven't been able to determine the import path for IContextProvider as the compiler complains it does know what it is. So I'm unable to use Mattes code to setup the context in tasks.

                         

                        As for the problem of setting up the context, this is starting to get a bit circular. I think using the task framework to chains commands is very clean, it just the the task framework is pre-Parsley and I yet to find a working example of using tasks and messaging together in Parsley 2.4. Mattes example comes close, although he refers to 2.3.

                         

                        I guess the messy coupling of commands together may have to do as I've almost got it working.