1

I'm calling an oData v2 service with an $expand parameter so the url looks like this:

https://host/odata/v2/myEntity?$expand=key4

and I am returned an oData json object which looks like this:

{
   "d": {
      "results": [
         {
            "key1": "val1",
            "key2": "val2",
            "key3": "val3",
            "key4": {
               "results": [
                  {
                     "key5": "val5",
                     "key6": "val6",
                     "key7": "val7"
                  }
               ]
            }
         }
      ]
   }
}

Once I receive the oData object, in my controller.js I create a JSONModel object like so and assign it to the viewModel:

var oJson = new sap.ui.model.json.JSONModel(oData);
this.getView().byId("tableId").setModel(oJson, "myModel");

Next, in my View.xml I have a table with the id "tableId" which binds this myModel as so:

<Table id="tableId" items="{path: 'myModel>/results' }">

With the above I am able to retrieve the values for key1, key2 and key3 in the table by doing:

<Text text="{myModel>key1}" />

But I cannot get the values for the results array under key4 to access key5, key6 and key7. How do I achieve this please?

  • How would you like to display the `key4` values? As you can see, it's a collection. I.e. you'd need another aggregation binding. It's not clear what you mean exactly by "get the values". – Boghyon Hoffmann Dec 27 '20 at 15:34
  • Btw.: there is no need for a JSONModel if you're dealing with OData. Simply bind with the existing ODataModel. Do **not** use `.read`. – Boghyon Hoffmann Dec 27 '20 at 15:35
  • Hello Boghyon, thanks for your comments, I have edited my question to add some clarification. You mentioned aggregation binding. How do you do that to bind the values of everything under key4 to the same table? – user1567874 Dec 27 '20 at 22:06

1 Answers1

0

You mentioned aggregation binding. How do you do that to bind the values of everything under key4 to the same table?

Depends on how you'd like display the key4 values. Since .../key4/results is a collection, same as /d/results, you could, for example, create another table / list control that shows items from the key4 that was selected from the 1st table via context binding. It's not possible to bind key4 in the same table.

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
  • Hi Boghyon, so if we cannot bind /key4/results to the same table, is it ok to use Javascripts onInit() method of the controller to read the oData, and then programmatically set the values to text elements inside the same table? That way all the data can show in one table? – user1567874 Dec 31 '20 at 01:52
  • @user1567874 I recommend declarative approach without manually calling `.read` in controller. Maybe I misunderstood what you mean by binding key4 on the same table. Please update the question with a wireframe or mock-up that shows clearly how you'd like to display the nested data in one table. – Boghyon Hoffmann Dec 31 '20 at 09:25
  • So if you imagine a Table that will include column headers key1, key2, key3, key5. key6, key7. I can get key1-3 to display in the table through table items binding, but not key5-7 because those are nested. – user1567874 Jan 04 '21 at 18:27
  • @user1567874 I suggest going through [OpenUI5 - _Get started_](https://openui5.hana.ondemand.com/topic/8b49fc198bf04b2d9800fc37fecbb218) first. Especially the walkthrough. I understand that you want to somehow display key5-7 in the same table, which is feasible by **hardcoding the index number**, but that's a very unusual unscaleable approach in real world business scenarios. The key5-7 depend on one single row from the first table. Unless you want to display the nested values in the same row (again, very unusual), you'll have to use another control that displays those nested values. – Boghyon Hoffmann Jan 04 '21 at 19:27
  • The issue is displaying the parent and child ($expand=key4) in the same row of the table. With the binding approach all the parent values are displayed in the table but their corresponding child values do not display even if the odata service returns them there is NO way to bind the nested child node values (in this case items under key4) to the same table. It seems the only way this might be achievable at this point is to use the controller to retrieve the values under key4 and bind them to the Text element in the table at runtime in the onInit() method. If you know a better way lmk – user1567874 Jan 04 '21 at 22:03
  • @user1567874 I need to know how you'd like to display the nested values in the same row, as requested in my [previous comment](https://stackoverflow.com/questions/65432057/sap-ui5-how-do-you-read-the-data-in-a-nested-odata-object-in-javascript/65471907?noredirect=1#comment115835017_65471907). A wireframe or mock-up would be nice. Should the values be comma separated? – Boghyon Hoffmann Jan 04 '21 at 22:07
  • there is really nothing complicated about the way i wish to display the values. If you imagine a sap.m.Table control with 6 column headers, namely key1,2,3,5,6,7. Each row of the table has a sap.m.Text control. I wish to bind the values of each key to the relevant text element under the respective header. Key1,2,3 binds without issues. It is key5,6,7 that I cannot get to display as its the nested structure. – user1567874 Jan 05 '21 at 19:09
  • @user1567874 The issue is the current data model. Let's say key1-3 belong to *EntitySet_A* which has key4 as a `` expanding to **many** *EntitySet_B*. Since it expands to **many** entities, instead of a single entity, you have a collection and thus can access the values only through a hardcoded **index** (i.e. binding `ToEntityB/0/key5`, `ToEntityB/0/key6`, and `ToEntityB/0/key7` in `sap.m.Text`). With *EntitySet_A* expanding to a single entity, it's possible to bind texts without the index. But then you'd have to change the data model accordingly in the OData service. – Boghyon Hoffmann Jan 05 '21 at 23:37
  • Hi Boghyon,, Thanks for your reply. There is exactly only one key4 entity (from your example EntitySet_B) and many EntitySet_A. So for example, if there are 10 entries in the EntitySet_A array, there will only be one EntitySet_B (at array element 0) per EntitySet_A element. Hope that adds additional clarity. – user1567874 Jan 06 '21 at 16:23
  • @user1567874 If *EntitySet_A* has only one related entity from *EntitySet_B*, then that definition should be also reflected in service `$metadata` document. E.g. in Northwind service, [a Product has a cardinality of `0..1` to a Supplier whereas a Supplier can be assigned to `*` (many) Products](https://services.odata.org/V2/Northwind/Northwind.svc/$metadata) (See association `FK_Products_Suppliers`). This can be seen in the data load as well: https://services.odata.org/V2/Northwind/Northwind.svc/Products?$expand=Supplier&$format=json (Supplier is a single object instead of a `results` array). – Boghyon Hoffmann Jan 06 '21 at 16:36
  • @user1567874 Is your OData service developed in SAP Gateway? There is apparently an _[Association Wizard](https://help.sap.com/viewer/68bf513362174d54b58cddec28794093/latest/en-US/07dc22512c312314e10000000a44176d.html)_ to help you assign the cardinality correctly where you can set `N`, `M`, `1` or `0` accordingly. In our case, `1` or `0` would be appropriate since *EntitySet_A* expands to a single entity from *EntitySet_B*. Unfortunately I'm lacking in expertise in backend. Whatever tools you use to create the OData service, it should be possible to set the right cardinality between entities. – Boghyon Hoffmann Jan 06 '21 at 16:55
  • The odata service is on the SuccessFactors platform. Custom objects are created through MDF. The oData service are generated by SAP's internal workings within the SF platform, so it's not as flexible as building the custom service in tcode SEGW (Gateway service builder). – user1567874 Jan 06 '21 at 19:22
  • @user1567874 Are "custom objects" in SF "Entity types" in OData? – Boghyon Hoffmann Jan 06 '21 at 19:46
  • @user1567874 Try searching by "multiplicity", "association" or "cardinality" in the official documentation of the platform you're using. If the platform lets you create entity types (e.g. *EntitySet_A* and *EntitySet_B*), then there must be also a configuration option for setting the relationship between the entity types correctly (E.g. a house belongs to one city. A city has many houses). – Boghyon Hoffmann Jan 06 '21 at 20:00
  • @user1567874 Let me know if you were able to create a navigation property to a single *EntitySet_B* entity. – Boghyon Hoffmann Jan 16 '21 at 14:05