cancel
Showing results for 
Search instead for 
Did you mean: 

OData plugin inclusion on a Cordova Windows project

Former Member
0 Kudos

Hi all,

I am having difficulties using offline OData in my Cordova application for Windows platform.

The application can successfully create an offline store and do an OData.read() call when the device is online. However, when the device is offline, the OData.read() call will fail with message "HTTP request failed".

Accepted Solutions (1)

Accepted Solutions (1)

midhun_vp
Active Contributor
0 Kudos

Hi,

What is the version SMP SDK you are using? Win 8.1 supports offline only from version SMP SDK SP07.

Regards, Midhun

SAP Technology RIG

Former Member
0 Kudos

Hi Midhun,

I didn't mean to post this so fast. I meant to provide a lot more detail. Seemingly I can't delete or edit that message so I'll "redo" that message right here.


Hi all,

I am having difficulties using offline OData in my Cordova application for Windows platform.

The application can successfully create an offline store and do an OData.read() call when the device is online. However, when the device is offline, the OData.read() call will fail with message "HTTP request failed".

(continued)

Here is the code I am using :


function openStore() {

        console.log("store.open called");

        if (!haveAppId()) {

            return;

        }

        var properties = {

            "name": "Emergency",

            "host": applicationContext.registrationContext.serverHost,

            "port": applicationContext.registrationContext.serverPort,

            "https": applicationContext.registrationContext.https,

            "serviceRoot": appId, 

            "definingRequests": {

                "Products": "/Products"

            }

        };

        store = sap.OData.createOfflineStore(properties);

        store.open(openStoreSuccessCallback, errorCallback);

}

function openStoreSuccessCallback() {

        console.log("Store is OPEN.");

        sap.OData.applyHttpClient();

        setModel();

}

function setModel() {

/*

        // Option 1

        var uri = applicationContext.applicationEndpointURL;

        var user = applicationContext.registrationContext.user;

        var password = applicationContext.registrationContext.password;

        var headers = { "X-SMP-APPCID": applicationContext.applicationConnectionId };

        var oModel = new sap.ui.model.odata.ODataModel(uri, {

            json: "true",

            user: user,

            password: password,

            headers: headers

        });

          

        sap.ui.getCore().setModel(oModel);

        oModel.read("/Products", {

            async: false,

            success: function (oEvent) {

                console.log("getdata1 successful");

                var msg = new Windows.UI.Popups.MessageDialog("Reading from the model has succeeded");

                msg.showAsync();

            },

            error: function (err) {

                console.log("you have failed");

                var msg = new Windows.UI.Popups.MessageDialog("Reading from the model has failed");

                msg.showAsync();

            }

        });

*/

        // Option 2

        var sURL = applicationContext.applicationEndpointURL + "/Products";

        var oHeaders = {};

        oHeaders['Authorization'] = authStr;

        oHeaders['X-SMP-APPCID'] = applicationContext.applicationConnectionId;

        oHeaders['Content-Type'] = "application/json";

        oHeaders['X-CSRF-Token'] = "FETCH";

        var request = {

            headers: oHeaders,

            requestUri: sURL,

            method: "GET"

        };

        OData.read(request,

            function (data, response) {

                console.log('success');

                var msg = new Windows.UI.Popups.MessageDialog("success");

                msg.showAsync();

            },

            function (err) {

                console.log('fail');

                var msg = new Windows.UI.Popups.MessageDialog("fail: " + err.message);

                msg.showAsync();

            }

        );

    }

I have tried different backend URLs (my REST enabled web application as well as the Northwind services), as well as simplifying everything on the Mobile Services side as much as possible (no authentication, etc.) with the same result.

This code works, but only when the device is online. When the device is offline, the OData.read() call will fail (as stated previously) with the message "HTTP request failed" although the store will be successfully opened.

When I use cordova to build the project, Cordova generates a Visual Studio project. The VS project does not generate an .exe file (only .appx files which would need to be signed and sideloaded) so I run the app in VS, then pin it to the taskbar and open it from there, in order to ensure the app is not rebuilt with a new store every time I run it.

I am thinking the problem may be a dependency issue. When I use the Cordova CLI to add the OData plugin, I get the following output:

        **********************************************************

        * Manual steps required to add this plugin on Windows 8.1 and Windows Ph

one 8.1 only.

        *

        * This plugin requires a Native windows references that cannot be added

automatically.

        *

        * ADD NATIVE REFERENCES FOR THE WINDOWS 8.1 PROJECT

        * 1) Open the Cordova generated solution in Visual Studio.

        * 2) Select the project generated for Windows 8.1. Select the References

node, Right Click and select "Add Reference".

        * 3) Click "Browse", locate the OfflineOData plugin location on your dis

k ({OfflineODataPluginDirectory}/windows81/bin/win)

        * 4) Select *.winmd and *.dll file for the appropriate CPU architecture

of your project (x86 or x64 or ARM). This file is located in {OfflineODataPlugin

Directory}/windows81/bin/win/[x86 or x64 or ARM]

        * 5) Select "Windows 8.1" -> "Extensions" and select "Microsoft Visual C

++ 2013 Runtime Package for Windows (Version 12.0 or higher)".

        * 6) Click OK to add the references.

        *

        * ADD NATIVE REFERENCES FOR THE WINDOWS PHONE 8.1 PROJECT

        * 1) Open the Cordova generated solution in Visual Studio.

        * 2) Select the project generated for Windows Phone 8.1. Select the Refe

rences node, Right Click and select "Add Reference".

        * 3) Click "Browse", locate the OfflineOData plugin location on your dis

k ({OfflineODataPluginDirectory}/windows81/bin/wp)

        * 4) Select *.winmd and *.dll file for the appropriate CPU architecture

of your project (x86 or ARM). This file is located in {OfflineODataPluginDirecto

ry}/windows81/bin/wp/[x86 or ARM]

        * 5) Select "Windows 8.1" -> "Extensions" and select "Microsoft Visual C

++ 2013 Runtime Package for Windows Phone (Version 12.0 or higher)".

        * 6) Click OK to add the references.

        **********************************************************

However, Visual Studio only allows me to add references with the .winmd extension. I cannot add the .dll references - apparently, in Windows 8 projects only .lib files which come from .dll files can be added, of which I have none for the OData plugin.

Could this be the problem? I am unsure as it does work when the device is online, even with only the .winmd references added. If so, how would I solve this? Has this issue been come across before?

To your question :

The Kapsel SDK version I am using seems to be 3.8.0, and the SMP SDK would be SP08, judging by different files in the KapselSDK directory.

(Most of what I wrote here, I wrote as a comment in the other post this morning, but I figured it would be cleaner to create a new post for it).

Christopher

former_member220979
Participant
0 Kudos

Hi Christopher,

The reason might be that the request to read the data in offline mode is still hitting GW service instead of reading from offline store. Verify using any network tracing tool like Fiddler. Can you add sap.oData.applyHttpClient() before OData.read call in Option2 code snippet.

If the Windows depedency objects are not added correctly in app, then call to sap.OData.applyHttpClient() will crash the app.

Chirag.

Former Member
0 Kudos

Hi Chirag,

Fiddler does in fact show that there are outbound requests to the backend system when the application is launched in offline mode. That is very helpful. I however do not understand why - the configuration seems correct, I have tried a lot of different combinations between the store settings and the OData.read() call parameters, and none seem to work.

I tried moving sap.OData.applyHttpClient() to where you said but it doesn't change anything.

midhun_vp
Active Contributor
0 Kudos

Hi Christopher,

Is this app working in other OS?

I just want to check whether this is an issue only in Win.

Regards, Midhun

SAP Technology RIG

former_member220979
Participant
0 Kudos

Hi Christopher,

Please check following 2 points:

1. Store is opened successfully. If not, check the SMP Server logs.

2. datajs is loaded successfully in index.html using <script src="js/datajs-1.2.2.js"></script>

Also I feel that XCSRF-TOKEN is not required for offline read request.

Thanks,

Chirag.

Former Member
0 Kudos

Hi Midhun, Hi Chirag,

Quick update: having noticed with Fiddler that there were outbound requests even in offline mode, I stepped into the OData.read() method: it turned out that I was being switched to the default store and the offline store was not being used because the store was registering with the HCPms URL whereas I was trying to read from the endpoint URL directly.

What I did, then, was replace the backend system with the Northwind services, which don't require routing through the HCPMS, and this worked offline.

I then came back to my initial backend system, but tried bypassing the MS in my store creation and read requests, and querying straight from the endpoint URL, but got the following error :


"{\"errorCode\":\"2\",\"errorMessage\":\"[-10028] Error at URL position 1: \\\"Products\\\" is not an entity set in entity container \\\"DemoService\\\"\",\"errorDomain\":\"OfflineStoreErrorDomain\"}"

Very much like the error reported here Problem with opening two online and offline sto... | SCN  , and this occurs both in online and offline mode.

Not sure what this can be related to, since the URL is correct and the "Products" entity definitely exists there. I'm trying to investigate.

Note: all this was accomplished using the OData.read() method. I have not yet managed to retrieve data from the offline store using the oModel.read() method.

So to answer your question Midhun, this is not a Windows platform issue as I initially suspected. Chirag, the store is opened successfully and the datajs-1.2.2.js library is loaded correctly.

I will keep you both updated with my progression.

Christopher

midhun_vp
Active Contributor
0 Kudos

Hi Christopher,

Could you provide me the SMP admin cockpit configurations.

I could see that, to the serviceRoot field you are passing AppId. Instead of appId could you pass the url in this format.

"serviceRoot" : "http://smpserverhot:8080/com.mycompany.offline/"


as given in this sample code: http://scn.sap.com/servlet/JiveServlet/download/58069-6-380524/index1UI5.html.zip


While making request if the service url is not matching with the offline url defined under serviceRoot, it always makes actual request instead of making a request to the offline store.

Regards, Midhun

SAP Technology RIG

Former Member
0 Kudos

Midhun,

That is exactly the problem - the OData library compares the host, port, path and scheme of the store URL and of the request URL. If they do not match then the request is sent using the default HTTP client. In the Kapsel SDK tutorials I have followed, the store URL points to the HCPMS app URL, whereas the request URL points to the endpoint URL. I don't understand how this strategy could ever work unless I change the store properties to match the URL of the request, thereby bypassing the HCPMS app proxying.

I tried changing the format of the serviceRoot, but the end result is unchanged. I don't see how that could be related.

Concerning the HCPMS application configuration :

- ID : org.services.odata

- Name: Northwind

- Type: Hybrid

- Disable same-origin policy

- Basic authentication

- Proxy type : internet

- No authentication to backend

- Rewrite URL on HCPms

midhun_vp
Active Contributor
0 Kudos

Hi Christopher,

I always have low confidence on the northwind service.

I have recently faced weird issues in the apps I have developed using northwind. Especially when it is used with kapsel offline template in web IDE.

Hence for all of my demos I am using a different Odata service which has all pre-requisites of offline. I am sharing it with you for test purpose through DM. Test it and let me know how it goes.

Regards, Midhun

SAP Technology RIG

Former Member
0 Kudos

Midhun,

Thanks to your help I've now got it working.

The causes of the problem were:

- The offline store limitations which were not respected in the data or in the fields properties

- The following condition which I was not aware of: "If the primary key of an odata collection is a string, then the maxlength field should be mentioned"

Many thanks to Chirag and yourself for your help.

Christopher

Answers (0)