BonitaBPM how to get nested Business models on UI Designer variable

57 Views Asked by At

First let's check my models:

Documento
Revisao (A Documento can have multiple revisions)
Revisor (A Revisao can have one Revisor)


I have one task where I have to show - update the Documento's Revisao list. On execution/form, I have created a new UI Desginer form, and many data is generated.

On the form, I have the variables:

documento ../{{context.documento_ref.link}}
documento_revisoes {{documento|lazyRef:'revisoes'}}

Im tryng to show the Revisao list on a contanier and see no problem using documento_revisoes as collection value in a container widget. The problem start now:

This is a sample value of documento_revisoes:

[
    {
        "persistenceId": 3, 
        "persistenceId_string": null, 
        "persistenceVersion": 0, 
        "persistenceVersion_string": "0", 
        "comentario": "muito ruim!", 
        "resultado": false, 
        "links": [
            { 
                "rel": "revisor", 
                "href": "/API/bdm/businessData/br.xxx.company.model.Revisao/3/revisor" 
            }
        ], 
        "revisor": null
    }
]

I can't access the revisor attributes, because it was no loaded.

I try access the revisor values using

$item.revisor.login

But get nothing (as spected)

Question: How can a load the Revisor value on all instances on Revisão List?
Can I use the "links" attribute? How?

1

There are 1 best solutions below

0
Jonatan Cloutier On

I got it to work, but it's a bit painful. The reason why it doesn't work in a simpler way is that lazyRef need to have an instance item in input and it output the link url that can then be used to fetch the lazy data. But if we use the filter inside a declared variable for and external api call, we cannot provide a single instance item when we have a collection. The solution is thus to be able to dynamically call the external api when iterating on the collection. I added this as a js asset to my form


function getLazyLink(object, ref){
  const link = object.links.find((d) => d.rel === ref)
  return ".."+ link.href
}

angular.module('bonitasoft.ui.extensions')
  .filter('reqLazyRef', function($timeout) {
    var data = new Map(),
        serviceInvoked = new Map();

    function realFilter(input, options, field, href) {
        return data.get(href)[field];
    }

    filterStub.$stateful = true;
    function filterStub(input, options, field) {
      const href = getLazyLink(input, options)
      if( !data.has(href) ) {
          if( !serviceInvoked.has(href) ) {
              serviceInvoked.set(href, true);
              
              fetch(href, {
                method: "GET"
              }).then(function(result) {
                  return result.json();
              }).then(function(json) {
                $timeout(function() {
                    data.set(href, json)
                }, 1);
              });
          }
          return "...";
      }
      else return realFilter(input, options, field, href);
    }
    
    return filterStub;
});

then can be used as {{ $item | reqLazyRef : "revisor":"login" }}

The angular explanation of why the filter work like this come from this answer: https://stackoverflow.com/a/19051656/314198