How can I ensure a command is always injected with a payload even if one isn't passed?

kamcknig's Avatar

kamcknig

02 Aug, 2015 04:48 PM

I have a command that runs that I want to have a timeout that is customizable.

//my config class, i map SomeCommand to SomeEvent
public class Config implements IConfig
{
    public function configure():void
    {
        commandMap.map(SomeEvent.SOME_TYPE).toCommand(SomeCommand);
    }
}

//SomeCommand class that gets injected with a TimeoutVO
public class SomeCommand
{
    [Inject]
    public var timeoutVo:TimeoutVO;

    public function SomeSomeCommand():void
    {
        trace(timeoutVo.timeout);
    }
}

//TimeoutVO that just holds an integer
public class TimeoutVO
{
    public var timeout:int;

    public function TimeoutVO(timeout:int=30):void
    {
        this.timeout = timeout;
    }
}

//bootstrap command that uses macrobo sequecnce macro to run some commands
public class BootstrapCommand
{
    public function BootstrapCommand extends SequenceMacro
    {
        //add some commands
        add(SomeCommand).withPayloads(new TimeoutVO(25));;
        //add some other commands
    }
}

The bootstrap works just fine. If I create the TimeoutVO payload with 25 then the command traces 25 if I leave it blank it traces 30.

My question is: how do I ensure that the command is always injected with a timeout even if I don't/can't pass a payload. For example, what If I did:

add(SomeCommand)

Or my instance what I really might do later is dispatch SomeEvent.SOME_TYPE and I'll want the command to run from the mapping I created in the config.

Will I just have to pass a TimeoutVO in SomeEvent and then in SomeCommand check if the event has a TimeoutVO and that will just override the injection of TimeoutVO if it exists? Or is there some other way to do this with RL2?

Thanks!

  1. 1 Posted by greenLED on 03 Aug, 2015 04:55 AM

    greenLED's Avatar

    Hi kamcknig

    Macrobot executes commands in an isolated environment using a
    sub-injector, so anything you map at an higher level can be used in the
    commands.

    You could try to map a TimeoutVO instance in your context as the default
    value, and then pass or not another one in the payloads. If you don't
    pass a payload, the command should get th default value mapped in the
    context. If you do pass a payload, it should replace the parent mapping.

    El 02/08/2015 a las 11:48, kamcknig escribió:

  2. Support Staff 2 Posted by Ondina D.F. on 03 Aug, 2015 11:24 AM

    Ondina D.F.'s Avatar

    Hi,

    My question is: how do I ensure that the command is always injected with a timeout even if I don't/can't pass a payload. For example, what If I did: add(SomeCommand)

    You can try to make the injection optional:

    SomeCommand

    [Inject (optional=true)]
    public var timeoutVo:TimeoutVO;
    

    same for the event, if need be:

    [Inject (optional=true)]
    public var someEvent:SomeEvent;
    

    This way you are free to add a command to the sequence of commands with or without a payload and also to run the command by dispatching the event to which it was mapped in your config.

    Does this solve your problem?

    Ondina

  3. 3 Posted by kamcknig on 03 Aug, 2015 10:06 PM

    kamcknig's Avatar

    Yep!

    Unless you have a better way to do what I'm trying to accomplish then that answers it!

    Thanks so much

  4. Support Staff 4 Posted by Ondina D.F. on 04 Aug, 2015 11:39 AM

    Ondina D.F.'s Avatar

    You're welcome!

    There are a few ways to do that, but I don't know if they are any better than your solution. As always, it depends on your requirements what's best.

    1 TimeoutVO is injected into every class that dispatches SomeEvent that triggers SomeCommand.

    timeoutVO.timeout is set to a new value before dispatching the event (or before running the macro commands) and the command, which is also injected with TimeoutVO, reads the vo's value. SomeEvent has no payload, thus you don't need to inject it into the command.

    2 SomeEvent has a property timeout with a default value = 30. SomeEvent is injected into SomeCommand and into the BootstrapCommand or is created there. Before adding the command to the sequence of commands, someEvent.timout is set to the desired value.

    someEvent.timeout = 25;
    add(SomeCommand).withPayloads(someEvent);
    

    3 SomeEvent has a property timeoutVO. You inject SomeEvent into BootstrapCommand or create a new SomeEvent, then set the value of SomeEvent's vo:

    var someEvent:SomeEvent = new SomeEvent("");
    someEvent.timeoutVO = new TimeoutVO(25);
    add(SomeCommand).withPayloads(someEvent);
    

    SomeCommand has only someEvent as a dependency. There you read the value of someEvent.timeoutVO.timeout.

    I'd use the 3rd solution, because I don't need to inject the VO into the command as well and because I can send a strongly typed payload with the event dispatched from elsewhere, if need be.

    I can't think of other solutions right now.

  5. Support Staff 5 Posted by Ondina D.F. on 04 Aug, 2015 11:41 AM

    Ondina D.F.'s Avatar

    @greenLED I just saw your message and merged it with this discussion. It was a private message (not visible to the public) and also as a separate thread. I suspect, that happened because you were answering through email. Either the tender forum has a bug, or you set a private flag in your email when you answered. You should try answering directly in the browser after logging in into the forum.

    Anyway, thanks for participating to the discussion.

    Macrobot executes commands in an isolated environment using a sub-injector, so anything you map at an higher level can be used in the
    commands.

    That's true with the exception of events that were mapped to a command by the eventCommandMap. In order to get the event injected automatically into a command that is run through the macrobot, you'd either have to create a mapping for the event using macrobot's injector, or to simply add the command withPayloads(someEvent);

    You could try to map a TimeoutVO instance in your context as the default value, and then pass or not another one in the payloads. If you don't
    pass a payload, the command should get th default value mapped in the
    context. If you do pass a payload, it should replace the parent mapping.

    That's a good idea!! The mapping would look like this:

    var timeoutVO: TimeoutVO = new TimeoutVO (30);
    injector.map(TimeoutVO).toValue(timeoutVO);
    

    However, I'd prefer a solution where you wouldn't need to inject both, a VO and an Event with the VO as a payload.

  6. 6 Posted by kamcknig on 04 Aug, 2015 12:14 PM

    kamcknig's Avatar

    Great!

    Thanks so much for the answers.

    @greenLED yeah I didn't even see your response until @Ondina added it here.

    All great solutions that I wouldn't have though of but all make their own sense.

    However, I'd prefer a solution where you wouldn't need to inject both, a VO and an > Event with the VO as a payload

    That' what I was hoping for, to not have to inject both and test of the existence of one or the other!

  7. Support Staff 7 Posted by Ondina D.F. on 04 Aug, 2015 01:20 PM

    Ondina D.F.'s Avatar

    Just a variant of my 3rd solution from the previous post, where only SomeEvent is injected into SomeCommand.

    SomeEvent:

    private var _timeoutVO:TimeoutVO;
    
    public function SomeEvent(type:String=null, vo:TimeoutVO=null, bubbles:Boolean=false, cancelable:Boolean=false)
    {
        
        _timeoutVO = vo || new TimeoutVO ();//default 30
        
        //or
        //_timeoutVO = vo || new TimeoutVO (90);
    
    
        super(type, bubbles, cancelable);
    }
    public function get timeoutVO():TimeoutVO 
    {
          return _timeoutVO;
    }
    
    override public function clone():Event
    {
        return new SomeEvent(type, timeoutVO, bubbles, cancelable);
    }
    

    BootstrapCommand

    ...
    //this would trace the value set inside of the event, 90 or the default 30
    //add(SomeCommand).withPayloads(new SomeEvent(""));
    //or
    var someEvent:SomeEvent = new SomeEvent("something", new TimeoutVO (120));
    add(SomeCommand).withPayloads(someEvent);
    ...
    

    Some other class:

    dispatch(new SomeEvent(SomeEvent.SOME_TYPE, new TimeoutVO (5)));

  8. 8 Posted by kamcknig on 04 Aug, 2015 01:38 PM

    kamcknig's Avatar

    Perfect!

    I'll mark this as closed.

  9. kamcknig closed this discussion on 04 Aug, 2015 01:38 PM.

  10. greenLED re-opened this discussion on 04 Aug, 2015 06:55 PM

  11. 9 Posted by greenLED on 04 Aug, 2015 06:55 PM

    greenLED's Avatar

    Hi @ondina and thanks for pointing out the private/public thing. I never meant to make it private. I use to answer directly from mail because sometimes this forum loads very slow from my connection, but, lucky me, I tried again today and it is loading at a normal speed again, so welcome web forms :) Sadly, also saw some other mail answers marked as private, and aparently with no connection with original questions. Looks like I have been doing something very in the wrong way.

    Anyway, how could I flag my email answers as public?

  12. Support Staff 10 Posted by Ondina D.F. on 05 Aug, 2015 08:38 AM

    Ondina D.F.'s Avatar

    @greenLED I've never replied per email to discussions on this forum, hence I don't know much about Tender's email commands. There is a list of commands on Tender Support that can be used by staff members/supporters, but I'm not sure whether commands like # private or # public can be used by regular users as well.
    https://help.tenderapp.com/kb/email-integration/updating-discussion...
    When I receive an email from robotlegs forum, there is an additional info text telling me which commands I can use to reply per email, as a supporter.
    Something like this:

    You can use commands on a new line at the top of this email (more information):
    #resolve #acknowledge #spam #delete #queue #notify #ignore #public #private #internal
    

    I don't know what you see as a regular user. Is there anything about commands?

    The next message will be a test sent by email.

    @ kamcknig I'm glad to hear that you are back on track and sorry for the following emails about emails:) Just ignore us for the time being..

  13. Support Staff 11 Posted by Ondina D.F. on 05 Aug, 2015 08:44 AM

    Ondina D.F.'s Avatar

    This message has been sent by email.
    I've edited the original message, which was just garbage. Sorry.

  14. Support Staff 12 Posted by Ondina D.F. on 05 Aug, 2015 09:27 AM

    Ondina D.F.'s Avatar

    @greenLED I've created a new thread where we can test tender's behaviour:

    http://knowledge.robotlegs.org/discussions/feedback/1014-testing-te...

    I'm going to close this discussion.

  15. Ondina D.F. closed this discussion on 05 Aug, 2015 09:27 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac