Search code examples
odatasapui5sap-fiorisap-business-technology-platformui5-tooling

Not able to use OData V2 (Northwind) data in SAPUI5 App


I am trying to use Northwind data service (OData V2) in my SAPUI5 app. However, I am not able to get any data at all from the server.

This is my XML view:

<mvc:View controllerName="c.g.odataapp2.controller.Root"
  xmlns:mvc="sap.ui.core.mvc"
  displayBlock="true"
  xmlns="sap.m">
  <Page id="page" title="{i18n>title}">
    <Table id="idOrdersTable" items="{odm1>/results}">
      <columns>
        <Column>
          <Text text="OrderId" />
        </Column>
        <!-- ... -->
      </columns>
      <ColumnListItem>
        <Text text="{odm1>OrderID}" />
        <!-- ... -->
      </ColumnListItem>
    </Table>
  </Page>
</mvc:View>

This is controller code:

sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/ui/model/odata/v2/ODataModel"
], function (Controller, ODataModel) {
  "use strict";

  return Controller.extend("c.g.odataapp2.controller.Root", {
    onInit: function () {
      var oModel = new ODataModel("https://cors-anywhere.herokuapp.com/https://services.odata.org/V2/Northwind/Northwind.svc/Orders?$format=json");
      this.getView().setModel(oModel, "odm1");
    }
  });
});

Do I need to set up anything else (Not mentioned in the docs)? I have used proxy/https/...link.... but this seems to be not working as either.


Solution

  • There are mainly two issues in the question:

    1. Application code

      • Invalid service URL: when passing a string to the ODataModel constructor, the string needs to be pointing to the resource where the OData service serves the service $metadata document. Therefore, Orders?$format=json needs to be removed from the string.
      • Replace items="{odm1>/results} with items="{odm1>/Orders} in the view definition.
    2. Issue with CORS *

      The public demo proxy server cors-anywhere.herokuapp.com is no longer directly usable without having a temporary access requested first (See the related announcement).

      Instead, continue with the "Resolution" section from the documentation topic "Request Fails Due to Same-Origin Policy (Cross-Origin Resource Sharing - CORS)". Expand the subsection corresponding to your development environment.

      In case you're working locally without setting a destination in SAP BTP:

      • Expand and follow the subsection "Local Development: Configure a local proxy"
      • Or make use of the ui5-middleware-simpleproxy. Here is a sample ui5.yaml config with the middleware: https://github.com/boghyon/gitpod-ui5-basic/blob/main/ui5.yaml. Keep in mind to execute npm install ui5-middleware-simpleproxy --save-dev in your terminal beforehand. To configure the ui5-middleware-simpleproxy in ui5.yaml for consuming the Northwind service from odata.org, you could set:
        1. mountPath: /myODataService
        2. configuration/baseUri: https://services.odata.org
        3. And finally in your controller code:
          new ODataModel("/myODataService/V2/Northwind/Northwind.svc"); // without .../Orders?$format=json

      * With the exception of the OData V4 TripPin service, services from odata.org currently don't support CORS. To learn about CORS in general, see Same origin Policy and CORS (Cross-origin resource sharing).

      If the service doesn't support CORS, the service might report a vague report, for example:

      1. Client sends a preflight request with the method OPTIONS to see what kind of requests are allowed by the server.
      2. Server responds that it doesn't understand that OPTIONS request.
      3. Client reports "OPTIONS ... 501 (Not Implemented)".

    TL;DR

    In general, OData services from odata.org are poorly maintained, incomplete, and has many issues some of which I already reported at https://github.com/OData/ODataSamples/issues?q=is%3Aissue+author%3Aboghyon.

    Services from odata.org don't support generating CSRF tokens either. Add tokenHandling: false when defining the constructor settings for the v2.ODataModel class:

    new ODataModel({ // V2
      serviceUrl: "/myMountOrDestinationPath/...",
      preliminaryContext: true,
      defaultBindingMode: "TwoWay",
      tokenHandling: false, // prevents "HEAD ... 501 (Not Implemented)" from odata.org services
      // ...
    })

    👉 Instead of referring to services from odata.org, take a look at this blog post for alternative sample OData services maintained by SAP: "New SAP Gateway Demo System available".