1

I have made a title depending on variable how it's shown in: Title depending on other variable in SAPUI5

I would like to make the same with rows in sap.ui.table.Table so I tried:

rows="{= ${someData>/infos}.length > 0 ? ${someData>/infos} : ${someData>/result}}"

Whereas someData is an ODataModel (v2).

But got an error:

Uncaught TypeError: Cannot read property 'indexOf' of undefined

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
Michu93
  • 5,058
  • 7
  • 47
  • 80

2 Answers2

2

Problem

The problem is that you're trying to determine .length from an object. In ODataListBinding (someData>/infos), aggregations are resolved in an object rather than an array. Therefore the syntax can't work. Furthermore, the .length syntax implies that the whole collection is already available on the client-side, contradicting the purpose of sap.ui.table.Table.

Expression binding with .length makes only sense with a client-side JSONModel as mentioned here.

Alternative approach

There are multiple ways to define aggregation binding dynamically, but the most straight-forward solution would be just to access the table control reference and call bindRows dynamically. Something like this:

onInit: function() {
  this.loadCountOf("SomeSet", this.bindTableRows.bind(this));
  // ...
},

loadCountOf: function(entitySetName, handleCountSuccess) {
  const odataModel = /*...*/;
  odataModel.read(`/${entitySetName}/$count`, {
    success: count => handleCountSuccess.call(this, +count),
  });
},

bindTableRows: function(count) {
  this.byId("myTable").bindRows({
    path: count > 0 ? "/SomeSet" : "/TheOtherSet",
    // ...
  });
},

API reference: sap.ui.table.Table#bindRows

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
1

the errors seem to tell you that either infos or result is undefined. You should check the current value of those arrays.

Anyway, it's not a really good idea to bind table rows like that IMHO. What's you scenario?

StErMi
  • 5,389
  • 5
  • 48
  • 71
  • It's not empty because when I do: `{someData>/infos}` then it works, just can't do it with ternary operator. Well I generally have two arrays and always one is empty so I check the length and I know which one to use. – Michu93 Jan 07 '19 at 09:55
  • The scenario is really strange. It's possible that the ternary operator is not supported for this kind of binding (item aggregation) but it works for "normal" binding. Why do you have two different sources to display items? – StErMi Jan 07 '19 at 10:26
  • I get that model from external source. Sometimes I have to use `infos` array, sometimes I have to use `result` array. So the syntax is correct and it should work? – Michu93 Jan 07 '19 at 10:28
  • Yes the syntax should be correct. I think that the problem is to use that kind of binding to that aggregation. Try to move this kind of logic to the Controller side (I know, I'm not a huge fan of this solution). So get the data, check which one is not empty and assign it to a property of your model and use it. Set the list as busy until you get those info and then remove the busy state. – StErMi Jan 07 '19 at 10:44