How to fix an issue displaying data sets with numeric headers using widget TABLE (same for DATA TABLE)

Hi,
I need to display some data (initially read from an external file like csv, using Operations, data saved in the form of ArrayList in a pool variable type of java.lang.Object). In my data file first row - is the headers row, all the rest are just data to display in the table…
I’m using both widgets: **TABLE **and DATA TABLE. Now cases 1 and 2:

Case-1) There is NO problems when the data file has ordinary strings starting from letters (“what ever33”, “header1”, “FirstName” etc): all data rows displayed correctly, both widgets TABLE or DATA TABLE;

Case-2) When the data file has a headers starting from any digit (0…9, something like: “1”, “2nd Name” etc ) - then there is a problems displaying the data in the TABLE widget:

  • No data rows displayed, instead all rows are populated with the headers row repeatedly (see example);

widget TABLE properties:

  • Headers:
  • Content: <variable contains original data set in a ‘key’:‘value’, type of an array of objects, JSON>
  • Column keys:
    (for DATA TABLE only) - Data source: Variable

Example of input data source:

col1,2,3, 4Start,-5,6x,col7
row1-col1-data,row1-col2-data,row1-col3-data,row1-col4-data,row1-col5-data,row1-col6-data,row1-col7-data
row2-col1-data,row2-col2-data,row2-col3-data,row2-col4-data,row2-col5-data,row2-col6-data,row2-col7-data
row3-col1-data,row3-col2-data,row3-col3-data,row3-col4-data,row3-col5-data,row3-col6-data,row3-col7-data
row4-col1-data,row4-col2-data,row4-col3-data,row4-col4-data,row4-col5-data,row4-col6-data,row4-col7-data
row5-col1-data,row5-col2-data,row5-col3-data,row5-col4-data,row5-col5-data,row5-col6-data,row5-col7-data

This is what we can see in the output table:

col1,2,3, 4Start,-5,6x,col7 
row1-col1-data	2	3	{{ $eval(column, row) | uiTranslate }}	-5	{{ $eval(column, row) | uiTranslate }}	row1-col7-data
row2-col1-data	2	3	{{ $eval(column, row) | uiTranslate }}	-5	{{ $eval(column, row) | uiTranslate }}	row2-col7-data
row3-col1-data	2	3	{{ $eval(column, row) | uiTranslate }}	-5	{{ $eval(column, row) | uiTranslate }}	row3-col7-data
row4-col1-data	2	3	{{ $eval(column, row) | uiTranslate }}	-5	{{ $eval(column, row) | uiTranslate }}	row4-col7-data
row5-col1-data	2	3	{{ $eval(column, row) | uiTranslate }}	-5	{{ $eval(column, row) | uiTranslate }}	row5-col7-data

Chrome console messages:

vendor.min.js:105 Error: [$parse:syntax] http://errors.angularjs.org/1.3.18/$parse/syntax?p0=Start&p1=is%20an%20unexpected%20token&p2=2&p3=4Start&p4=Start
    at vendor.min.js:9
    at lb.throwError (vendor.min.js:195)
    at lb.parse (vendor.min.js:193)
    at vendor.min.js:113
    at b.$eval (vendor.min.js:129)
    at vendor.min.js:203
    at vendor.min.js:198
    at Object.<anonymous> (vendor.min.js:111)
    at m.$digest (vendor.min.js:126)
    at b.$apply (vendor.min.js:130)

Any ideas how to fix this issue?
Many thanks!

Thanks a lot for reporting this.

After doing some tests on my side I can confirm that this is an issue related to the usage of numbers in column keys definition.

I managed to reproduce the issue with a very basic table widget configuration. A table widget with column key such as col1, col2 behave as expected whereas two different incorrect behaviors can be seen when using column keys such as 1, 2 or 1col, 2col.

I have opened an issue on the community bug tracker that you can watched to be notified when it will be solved. The only workaround I can think of right now is to include a test in your form JavaScript code to make sure that column keys start with a letter.

Also with your current implementation content of the file will be stored twice: a first copy as a process document and a second in the process variable. In order to avoid this duplication you might want to create a REST API extension that can call Bonita Engine API to get the document content, do the parsing of the file and produce a JSON answer almost ready to be used in the table widget.

Hi,
To fix the Table issue you can create new custom widget based on the standard TABLE (or DATA TABLE), open it in Widget Editor and fix “Template” to replace “$eval(column, row) | uiTranslate” with “row[column]”. Something like that:

<tbody ng-if="ctrl.hasMultiColumns()">
<tr ng-repeat="row in ctrl.results" ng-click="ctrl.selectRowHandler(row)"
    ng-class="{'info': row === properties.selectedRow}">
    <td ng-repeat="column in properties.columnsKey track by $index">
        {{ row[column] }}
        <!--{{ $eval(column, row) | uiTranslate }} -->
    </td>
</tr>
</tbody>
<tbody ng-if="!ctrl.hasMultiColumns()">
<tr ng-repeat="row in ctrl.results" ng-click="ctrl.selectRowHandler(row)"
    ng-class="{'info': row === properties.selectedRow}">
    <td> {{ row[column] }}</td>
</tr>
</tbody>

This may not be an ideal fix but it works. Hope that helps…

Hi,

In your message you said “I’m using both custom widgets: TABLE and DATA TABLE” so I assuming your are not using the default widgets provided by Bonita. If this is correct can you share the links to download the custom widgets you are using?

Thanks

This must be just a typo.
Both are pretty standard widgets, no customization. Sorry for confusion.
I tried to modify one standard data table widget and created my custom, but that did not help anyway.

Can you share(using Google Drive, Dropbox…) your project? It will help me reproduce and potentially find a solution to your issue.

Also I would need some clarification regarding the data type you are using. Is it an ArrayList of List of String? Or maybe an ArrayList of your own data type definition?

Hi antoine.mottier,
I have created small sample to demo the case. I’m going to share it soon at dropbox/google dirve along with the data-source files (basic csv files contains few rows where first row is the header row):

  • a sample file that makes no problems (headers starting from letters),
  • a sample file that makes an issue due to the headers starting from numbers (please see those files);

To answer your question:

  • a source dataSet is passed in an ArrayList of List of String;
    Here is an example to read the file content into the ArrayList:

    ProcessAPI processAPI = apiAccessor.getProcessAPI();
    byte content = processAPI.getDocumentContent(csvDocument.getContentStorageId());
    String s = new String(content);
    List<List> lines = new ArrayList<>();
    String allValues = s.split(“\r\n”);
    for (String myStr : allValues) {
    List row = new ArrayList<>();
    String cells = myStr.split(“,”);
    for (String myDataCell : cells) {
    String nextLine = myDataCell.trim();
    row.add(nextLine);
    }
    lines.add(row);
    }
    return lines

Then store the result in a variable ‘listAllDataSet’ (data type: Java Object);

To display the dataSet in the form:
Set a variable ‘apiListAllDataSet’ = …/API/bpm/activityVariable/{{taskId}}/listAllDataSet
Another variable ‘jsColumnsList’ using javascript:

var arrays = $data.apiListAllDataSet.value[0];
let keys=[];  let j=0;
for (var x of arrays) {
    keys[j++] = (x.toString()).trim();
}
return keys;

And the last one - to form the list of JSON objects for a table widget:

var arrays = $data.apiListAllDataSet.value;
var keysArr = $data.apiListAllDataSet.value[0];
let keys=[]; let j=0;
for (var x of keysArr) {
    keys[j++] = (x.toString()).trim();
}
let values = arrays.slice(1);
var myMap = values.map(myMapFunc);
return myMap;
    function myMapFunc(value, index, array) {
      let key="";  let object = {};
        for (var i=0; i<value.length; i++) {
            key = keys[i].trim();
            object[key] = value[i];
        }
       return object;
    }

This is it. I hope I didn’t mess with the code…

Sample Project BOS archive (BonitaStudioCommunity-7.6.3):
https://drive.google.com/open?id=1zZy9dX9tZmKmSpfmWzpqkp70aJ3lYh45

Thank you!