Visual Builder

Get Involved. Join the Conversation.

Topic

    Ronald Konijnenberg
    Data in ADP different from what's being shown in list...Answered
    Topic posted September 18, 2019 by Ronald KonijnenbergGreen Ribbon: 100+ Points, tagged Action Flows, Business Objects, REST, Web 
    39 Views, 6 Comments
    Title:
    Data in ADP different from what's being shown in list view?
    Summary:
    Unexpected behavior when resetting/refilling ADP's used for list views.
    Content:

    Hello Community,

    Goal

    On page A, we want the user to be able to select items from one list and move them to another, so we both know what's selected and what's still available. Both the selected and available items should then be shown on page B.

    Approach

    We use two ADPs, one with available items and one with selected items. We fill the lis views with available items from a REST endpoint call. When a user selects an available item, we add the item to the selectedItemsADP and remove it from the availableItemsADP using two 'fire data provider events' in a single action chain. So far, so good. We got this working after learning about the proper use of the ADP's id attribute in this thread: https://cloudcustomerconnect.oracle.com/posts/7c27bb3923

    However, we also want to support the scenario where a user wants to start over and change the available items (show different, more or less items). This means we have to empty both ADPs and refill the available items ADP.

    To (re)set both ADP's, we use the following action chain:

    1. Call a REST endpoint
    2. Assign variables on the avaiableItemsADP using the endpoint call's output
    3. We empty the selectedItemsADP by doing a reset variables

    Problem

    We get unexpected behavior after resetting the ADP's. Initially the action chain shown above works fine. After a second run (reset) however, visually it looks like all is still ok, but  we found out that the length of the data array in the ADPs does not match the number of items that are being displayed.

    Example in our example-app: we have 3 truckdrivers that form our list of available items. You can move them to the list of selected drivers and back. If we choose to reset the lists, then availableItemsADP.data.length is 3, as expected. After this, adding drivers to the selectedADP does not change the length of either ADP (although visually it seems to function correctly). See screenshot and example app. This makes it impossible for us to use the availableItemsADP and selectedItemsADP on another page.

    Questions

    1. How can we reset both ADPs that are used for these lists, without getting this unexpected behaviour?
    2. Could this be related to this bug? The solution provided by Lalji does not work for us. https://cloudcustomerconnect.oracle.com/posts/7aaa4a3b28
    Version:
    19.1.3.11
    Image:
    Document:

    Best Comment

    Duncan Mills

    With an Array Data Provider the correct (and simplest) way to reset or change the contents of the provider is to assign a new array to the data property of the array.  Data Provider Mutation events should not really be used for that. 

    So to add a new row to the selected list your action chain should just call a method action that calls a function that will take the .data arrays in from both ADPs - (these will be clones) and the identity of the row you want to transfer

    In that method, you then remove the row from the source array and add it to the selected array and then return both arrays from the function.  Finally you have an assign variables action which will assign the respective outputs to the correct ADP data attributes again.  The UI should automatically refresh

    You can of course use the same page function code to handle the shuttling in either direction

    Comment

     

    • Duncan Mills

      With an Array Data Provider the correct (and simplest) way to reset or change the contents of the provider is to assign a new array to the data property of the array.  Data Provider Mutation events should not really be used for that. 

      So to add a new row to the selected list your action chain should just call a method action that calls a function that will take the .data arrays in from both ADPs - (these will be clones) and the identity of the row you want to transfer

      In that method, you then remove the row from the source array and add it to the selected array and then return both arrays from the function.  Finally you have an assign variables action which will assign the respective outputs to the correct ADP data attributes again.  The UI should automatically refresh

      You can of course use the same page function code to handle the shuttling in either direction

      • Ronald Konijnenberg

        Hi Duncan,

        Thanks for your fast reply, again!

        We'll try your suggestion and let you know how it went. It surprised us though that you say we shouldn't use data provider mutation events, as the documentation on the Fire Data Provider Event Action suggests that these can be used for ADP's: https://docs.oracle.com/en/cloud/paas/app-builder-cloud/visual-builder-developer/fire-data-provider-event-action.html

        Can you elaborate on why data provider mutation events shouldn't be used in our example, while we try your suggestion?

      • Ronald Konijnenberg

        Duncan, we tried your suggestion and it works.

        Here's the method we used:

        AppModule.prototype.verplaatsItemTussenArrays = function (vanArray, naarArray, itemIndex)
          {
          var returnArray = [];
         
          naarArray.push(vanArray[itemIndex]);
          vanArray.splice(itemIndex,1);
         
          returnArray.push(vanArray);
          returnArray.push(naarArray);
         
          return returnArray;
         
          };

        It proved to be essential to set the 'Reset Target' option in Assign Variables to 'empty', when replacing the ADP's existing data array with (one of the two arrays in) the output of the function.

        Thanks again!

    • Duncan Mills

      This article will explain how mutation events actually work and what they are used for:

      https://blogs.oracle.com/groundside/adventures-in-mutation-adding-rows-to-a-table-or-listview-in-oracle-visual-builder

      Your problem is caused by the fact that you are telling the UI control that a change has taken place in the Data Provider but in reality you have not actually made that change, the UI control takes you at your word and shows the change, however, it's now out of step with the actual data which was never changed. With an ADP you already have all of the data cached and in a form where you can change it locally so the scenarios where you need to use a mutation or refresh event are very limited (to the extent of I can't think of one). 

      • Ronald Konijnenberg

        Hi Duncan,

        I now also read your blog post. This really explained why our previous approach wasn't working. Maybe it's a good idea to use this blog post to improve the formal documentation?

        I also have a question considering the last part of your blog post that says "One nice side effect that you'll see of using this add mutation event is that when it happens the Table or ListView will animate the addition of the new row...". We already noticed that the user experience is a bit rough when replacing the data array of our ADP, instead of using the 'add' data provider event. The list view simply flashes and shows the new contents. Is there a way to have this smoothly animated, comparable to your example?

    • Duncan Mills

      Well I suppose you could use the mutation event to add to the table as well - as long as you have updated the source of truth (the underlying array) then when a hard refresh takes place the table will end up still showing the right data.