By Chris Malek | 25 April 2011
Avoid Global Variables with query string parameters
Global variables are evil! This is documented so well in so many blogs and computer science design books I will not cover it here other than to say this. If you are using a global variables in PeopleCode, you are probably doing something wrong and should think about an alternative. There are a few exceptions to this statement but they are rare.
One place where I often see PeopleCode developers use global variables is when they need to transfer from one component to another and pass some data between the components. For example, lets say that you have three different components that transfer to one common “destination component.” Let’s further assume that in this common “destination component” you need to do some specific logic based on what component a user transferred from.
So you might need to do something like this when the destination component loads:
If "source component" = 3 then /* do something special */ end-if;
What I often see in a situation like this is the developer will create a global variable in Source Component 3 and then look for it in the Destination component. This works but it can get ugly really fast because global variables are evil.
Using URL Query Strings
Lets look at an alternative method using URL Query string parameters.
Normally when you transfer from one component to another this is done through the Transfer Peoplecode function. In the Tranfer function, you can pass parameters between components by passing a record object to the target component that is based on the search record of that object. What really happens here behind the scenes is that PeopleTools looks at the search keys in the record object passed to the transfer function and creates query string key/value pairs based on the destination’s component search record. These are based on the common search keys on the record object you pass to the transfer function and what is defined on the target search record. Therein lies the issue. If you need to pass some additional piece of information that is not reflected in the search record then what do you do?
One alternative beside global variables is to use a slightly different method of doing the transfer. Instead of using the Transfer peoplecode function you can generate a URL for the target component and then tell the user’s browser to view it. This is really what the Transfer function is doing.
First you need to generate a URL using the GenerateComponentPortalURL function or one of the “sister” functions referenced in the documentation. There are a couple of variations of this function that generate slightly different URLs (with and without the portal wrapper, etc). You will have to experiment around with each one based on your needs.
This GenerateComponentPortalURL function will generate a URL to the target component and page. You can then append on another query string parameter that we will pickup later.
/* Generate some additional key value pairs */ &queryString = "&EMPLID=" | GetRow().MY_HDR.EMPLID.Value; &queryString = &queryString | "&SOURCE=3"; /* generate a url */ &url = GenerateComponentRelativeURL(%Portal, %Node, MenuName.MY_MENU, "GBL", Component.MY_COMP, Page.MY_PAGE, "U") ; /* Append on our parameters */ &url = &url | &queryString ViewURL(&url, False); /* You can also do this instead of viewurl: %response.redirectURL(&url) */
Then in the target component what you need to do is look for that parameters.
&source = %request.getParameter(“SOURCE”); if &source = "3" then /* do something special */ end-if;
There are some pros and cons of this approach.
- Lives for one request
- You will not run the risk of any other code over writing your variable and other perils of Global variables.
- It is not secure because anyone can set it in the URL so you have to use some common sense.