JavaScript: Running Code Only Once

By | 2014.10.29

Every time Cognos refreshes or reprompts a page any custom HTML objects and the JavaScript they contain are reevaluated and run again. There are times you may want a piece of JavaScript code in a Cognos HTML object to only execute one time. For instance, you may be setting initial default values or instantiating objects and don’t want values overwritten on a page refresh or reprompt. This post will outline a simple but effective technique to ensure that the code you designate won’t execute multiple times. This ability is crucial to advanced techniques such as prompt state maintenance.

The following events will force a re-render of a Cognos page and a re-run of any custom JavaScript code you have provided:

  1. A reprompt action is initiated, either through a standard reprompt button, selection of a cascading prompt, or JavaScript code
  2. The selection of a value prompt that has its ‘Auo-Submit’ property set to ‘Yes’ and all prompts are not valid
  3. A drill-up or drill-down action is initiated
  4. A rerun of the report is executed through the toolbar run button

A Bit About Cognos Reprompts and JavaScript Persistence

When Cognos reprompts a page all of the HTML controls on the page are recreated, just like hitting F5 to refresh any other Web page. However, any JavaScript variables or objects, whether created by us or Cognos, are not destroyed and persist after the reprompt. This is how Cognos retains your current prompt values on refresh. It pulls the values from the associated JavaScript prompt objects which survive the refresh/reprompt action. Interestingly, this persistence even holds true in multi-page prompt and report pages; variables, objects or functions created on the first page of a multi-page report can still be referenced on later pages.

We can take advantage of this behavior to determine whether our code has already run once and thus should be skipped.

Code

Here is a code snippet demonstrating the technique:

Example

Say you wanted to set the default value of a date prompt named ‘startDate’ to a week ago today. Setting dynamic prompt defaults is a very common usage of JavaScript as Cognos gives us very limited capability to do this out of the box. You want the default value to be set when the report first runs but if the page is reprompted, you want any changes to the prompt value by the user to be retained and not have it reset back to the default value.

You take the code setting the default and put it within the if statement in the snippet above:

On first run, the code inside the if block will be executed and the prompt will be set to seven days previous to the current date. If the user changes the prompt value and then reprompts the page the code setting the default value will be skipped as the firstRun variable will exist. Thus, the user’s selection will be preserved. Any other one-time run code can be added to the if block as necessary.

Explanation

We check if the variable firstRun already exists and if not we execute the code. At the end we create the variable so that next time the page is refreshed or reprompted the typeof check will return false and the code will be skipped.

Note that we are using a global variable, in this example firstRun. This variable can be any valid JavaScript variable name you like. However, care should be taken in naming this variable. The name should be unique since it could potentially collide with other variables declared in the global space, including variables Cognos itself declares. For this reason I recommend namespacing all variable and object names in Cognos custom JavaScript. This is a simple naming scheme that adds variables, objects,  and functions as properties or methods of a root object. Variables then are referenced with dot notation in relation to the root. If your root name was cjl, then the variable firstRun would be referenced as cjl.firstRun. I will cover namespacing in-depth in a future post.

With this simple bit of code you can isolate initialization code and have it run only once per report regardless of subsequent reprompt or refresh actions.

Update: 6-21-2017

After this article was published, I learned some new things about how Cognos handles object instantiation. When a page is reprompted, Cognos creates whole new object instances for all prompts and for the report itself. The old intances still exist but are effectively orphaned and no longer represent anything on the page. This means that any variable assignment to object instances has to take place on every reprompt. We want to get a reference to the newest instances of the object each time. Thus, these assignments cannot reside within the “first run only” section of the code. I have revised the sample code to reflect this.

8 thoughts on “JavaScript: Running Code Only Once

  1. Ritwej

    Hi Scott,
    This is very old post, hope I can reach to you by commenting here with my issue.
    I have used same technique in one my Cognos 11.10 report, it is working working fine if I run report from editor but it’ is throwing error when I run the report directly fro m the portal.

    Reply
    1. Scott E. Johnson Post author

      That’s strange. Unfortunately, I don’t have access to Cognos 11 and thus none of the code here was tested on it. That said, I believe that Cognos 11 supports the same JavaScript Prompt API that was introduced in version 10.2.

      Can you supply the error you are getting? I might be able to give you some insight.

      Reply
  2. Alex

    Brilliant. exactly what I was looking for. Thank you.

    Reply
  3. Dave

    Beautiful. A bit more fleshed out example would probably be helpful but thank you and keep em coming!
    Dave

    Reply
    1. Scott E. Johnson Post author

      Thanks for the feedback Dave. Based on your suggestion I’ve added an example section to show how the technique would be used in practice.

      Reply
  4. rameshwor

    Sweet Technique !!

    I used to do it with some default values set in the hidden prompts which would later be changed by the JS code. If the hidden prompt has the default value, then it is the 1st run.
    No onwards, ‘am gonna go with your technique.

    Thanks

    Reply

Leave a Reply