Discussion

How to avoid strange empty embedded pages

Pega is platform which allows us to create quite complex structures by embedding pages as property (single page or page lists), this is really strong mechanism to provide structural data. This approach simplifies UI creation and provides better modularity in both - back-end and front-end code, but unfortunately some constructions (in activities, when rules, sections etc) produces structures (empty pages) without data.

Is this a problem?

Sometimes - yes. Many developers creates their solutions based on specific conditions like

  • Page exists
  • Property exists

If we have the condition like ".somePage exists" we can expect that we are checking whether this page is initialised properly but it isn't and for example our UI which is based on this .somePage embedded page is broken. Why? In Pega platform the existence of property doesn't mean that it was initialised/created properly and intentionally. It is possible and quite common that some embedded pages (or properties) are created by accident and doesn't have any property - only the pxObjClass. In some use cases we can handle such situations by creating better conditions, for example - instead of checking "Page .somePage exists", we can try to extend it and create something like:
- Page .somePage exists and
- is initialised (by checking some property like pyLabel, or add some flag "isInitialised" and then check it)

But how to prevent such situation?

There are few possible causes for this issue and if we want to avoid it we can revisit some places of our implementation.

  1. Java code - if we want to check/use some embedded property value. First of all check if the embedded page exists, then check the property and its value. Example:
    1. String type = myStepPage.getString(".firstPage.secondPage.type")
    2. if (type!=null) {
    3. // do something
    4. }

    Note that this code will always run the logic from the "if" condition, what's more - you will end up with the empty .firstPage and .secondPage - so your logic changed the state of clipboard page. What can we do better here?

    1. ClipboardProperty firstPage = myStepPage.getIfPresent(".firstPage");
    2. String type = null;
    3. if (firstPage != null) {
    4. ClipboardProperty secondPage = firstPage.getPageValue().getIfPresent(".secondPage");
    5. if (secondPage != null) {
    6. ClipboardProperty typeProp = secondPage.getIfPresent("type");
    7. if (type != null) {
    8. type = typeProp.getStringValue();
    9. }
    10. }
    11. }

    Of course this code seems to be quite complex, it is possible to write it in short using different API methods to check the property existence but generally this example shows the difference and the clue of this: ClipboardPage.getString/getPage/getObject etc... will always create this ClipboardProperty in this page, but without value, so in case of Page property it ends up with empty structure. Instead of that you should use ClipboardPage.getIfPresent to check the existence of page/property before you get the exact value.

  2. When rules - if we want to check nested property like previous example and create condition as follows:
    Property .firstPage.secondPage.type Exists
    Obviously this will check the existence of "type" property correctly but as side effect we will get the .firstPage and .secondPage created. To avoid this we will need to improve this When rule and check existence of all nesting levels like:
    - @PageExists(.firstPage) AND @PageExists(.firstPage.secondPage) AND ... then we can check the property.
  3. UI rules - This is the most "hard to find" place but it is possible to avoid such situation here as well. The most popular cases are:
    - Visibility conditions with embedded properties - like .firstPage.secondPage.type != ""
    - Referencing embedded properties as control - like text input control with reference .firstPage.secondPage.type
    To fix them we need to set proper conditions on layouts to prevent displaying before it is initialised.

Summary

This is not a bug. In many places and use cases (I would say - mostly) this behaviour is correct and allows non-technical people to create the solutions without taking care of NPEs, broken structure etc. But in some situations we would like to avoid those empty structures. This article is only to provide some clues - why I have empty page in my clipboard and how to avoid it. This also shows the difference between .getIfPresent vs getObject/getProperty/getString/getPage... APIs methods - the first one allows you to check existence and could return NULL, the others will create the empty property and return it (which allows you to set value) - this is OK as well but from my experience it is quite common issue that those methods are wrongly used.

Comments

Keep up to date on this post and subscribe to comments