When One App Talks to Another, Good Things Happen!

As your repository of Valence apps grows, you may soon find occasion where you’d like to “spawn” one app from another in the Valence Portal. For example, you may have a simple inventory lookup app that you could launch whenever someone clicks on a line on a customer order, passing in the corresponding product number so the user doesn’t have to re-enter it manually. That same inventory lookup app could also be launched when clicking on an item in, say, a purchase order app. And so on. This kind of functionality inter-app functionality can serve as a great convenience your users. But what if the app you want to link to is already open in the Portal? i.e., if the inventory lookup app is already open, displaying data for one particular item, can it be made to switch to a different item by another app? Yes it can!  

First off, let’s cover the process for launching one Valence app from another and passing in pertinent details for the called app to use, such as, say, a product number. Within the Valence Portal this can be handled quite easily using the Valence helper function Valence.util.App.launch(). This function accepts as parameters the app ID to be launched (as listed in Portal Admin for each defined Valence app) and the parameter name(s) you want to pass to the called app.  For example, if your inventory lookup app had an app ID of 1234, and you wanted to pass it a product number via a parameter of “prdno”, the code might look like this:

Valence.util.App.launch({
     app: 1234,
     params: {
          prdno: product
     }
});

On the receiving end, your spawned app should check for passed in parameter(s) and act accordingly when found. This can achieved using the Ext.getUrlParam method. In our inventory lookup app example, assuming we’re using an MVC structure, this might be place inside a function of the controller that is called as part of an “after render” event, something like this:

onInquiryFormAfterRender: function() {
     // if app was just launched and a product was passed, call the inventory lookup function now...
     var inputPrdno = Ext.getUrlParam('prdno');
     if (inputPrdno) {
          this.lookupInventory(inputPrdno);
     }
}

So that handles launching the app and invoking the appropriate routine based on passed parameter(s).  If the called Valence app has no restriction on the number of instances that can be open (meaning, no setting on the “Maximum Open” in the app definition in Portal Admin), then each Valence.util.App.launch() call will launch a new instance of the app. In most cases, however, apps are defined with a max open of 1, in which case invoking the Valence.util.App.launch() would switch the user to the open instance of the app rather than launching a new instance. In this scenario, the URL parameters are not passed because they’ve already been set on the initial call. So if you want to have the open app detect the call and switch what it’s doing accordingly, you’ll need to use a different approach. To handle this within the Valence Portal you can use Valence.util.Helper.fireEvent() to fire a custom event that the called app can listen for. Going back to our example of calling an inventory lookup app, the resulting code might look something like this:

Valence.util.Helper.fireEvent('inventoryLookup_SwitchProduct',
                              {prdno: product});
Valence.util.App.launch({
     app: 1234,
     params: {
          prdno: product
     }
});

So now we have a custom event of “inventoryLookup_SwitchProduct” being fired from the calling app. This essentially “broadcasts” the event to all apps running in the Valence Portal, so any apps set to listen for the event (such as an inventory lookup app) can act accordingly. The subsequent Valence.util.App.launch() would then switch the user over to the desired app. The final step then would be to have the called app listen and act on the custom event using the Valence.util.Helper.addEventListener() function.  When the custom event is detected, the called app can be made to call a custom function to process the parameters passed in conjunction with the event. Our inventory lookup app, for example, could have the following code inserted into the “init” function of the controller definition:

Valence.util.Helper.addEventListener('inventoryLookup_SwitchProduct',this.onSwitchProduct,this);
...
onSwitchProduct : function(passedParms){
     if (passedParms.prdno !== undefined) {
         this.lookupInventory(passedParms.prdno);
     }
}

With this in place, you have all your bases covered: If the desired app is not yet running, the portal will launch it and put the user into the desired product. If it is running, the app will “hear” the custom event and switch to the desired product.