cancel
Showing results for 
Search instead for 
Did you mean: 

Odata Offline Hybrid application - Write

win_poojarahulb
Explorer
0 Kudos

HI all,

I am trying to build and odata hybrid offline based application using kapsel odata offline Plugin.

The below code is how I create an offline store and open store.


var properties = {

            "name": "EquipmentStoreOffline",

            "host": smphost,

            "port": smpport,

            "https": smphttps,

            "serviceRoot": appId,

            "streamParams": "custom_header=Authorization:" + authStr + ";",

            "definingRequests": {

                "eqheaderDR": definingrequests.EquipmentListDR

            }

        };

        store_EQ = sap.OData.createOfflineStore(properties);

        store_EQ.onrequesterror = onRequestError;

        store_EQ.open(openStoreSuccessCallback_EQ, unRegisterErrorCallback);


//open store success for equipment header

function openStoreSuccessCallback_EQ() {

 

    if (!store_EQ) {

        console.log("The store must be open before it can be refreshed");

        Ext.Msg.alert("Offline Store does not contain data !!");

        return;

    }

    if (navigator.onLine) {

        clearData();

        store.refresh(read_EQ, unRegisterErrorCallback);

        flushStore();

    }

    else {

        Ext.Msg.alert("You have gone Offline .Please verify your network connectivity.");

        sap.OData.applyHttpClient();

        var readlocal = "yes";

        read_EQ(readlocal);

    }

}


function read_EQ(islocal) {

    var oHeaders = {};

    oHeaders['Authorization'] = authStr;

    oHeaders['Content-Type'] = "application/atom+xml";

    var serviceUri = basesmpUrl

        + "/EQUIPMENT_MASTER_SET/?"

        + "$format=xml";

    console.log(serviceUri);

    if (islocal == "yes") {  //displays entities that have been created or updated but have not yet been flushed.

        if (store_EQ && store_EQ.getRequestQueueStatus) { //filter is a new features in SP06 of the SDK.  getRequestQueueStatus was added in the same SP.

            serviceUri = serviceUri + " and sap.islocal()";

        }

        else {

            alert("Displaying changed records that have not yet been flushed requires the offline store to be open and is a new feature in SP06 of the SDK");

        }

    }

    var eqstore = Ext.getStore("EquipmentStore"),

        localStore = Ext.getStore("EquipmentStoreOffline"),

        me = this;

    localStore.load();

    eqstore.removeAll();

    var request = {

        headers: oHeaders,

        requestUri: serviceUri,

        method: "GET"

    };

    OData.read(

        request,

        function (data, response) {

            for (var i = 0; i < data.results.length; i++) {

              

                var rec = {

                    Aufnr: data.results[i].Aufnr,

                    Equnr: data.results[i].Equnr,

                    BarcodeNo: data.results[i].BarcodeNo,

                    Eqktx: data.results[i].Eqktx,

                    Eqart: data.results[i].Eqart,

                    Completion: data.results[i].Completion,

                    Status: data.results[i].Status,

                    Header: data.results[i].Header,

                    Location: data.results[i].Location,

                    SubLocation: data.results[i].SubLocation

                };

                localStore.add(rec);

                localStore.sync();

            }

            var record = localStore.filter('BarcodeNo', FilterEQ);

            Ext.getCmp("eqgridpanel").setStore(localStore);

        },

        function (err) {

            console.log(err);

        }

    );

}

This is my code. I have a few questions on this.


1) I am not sure as of where to give flushstore() , clearstore() and closestore() as given in the example Right now I have given in " if(navigator.isOnline) " function. is this the right way?

2) There is a read_EQ function being called on refreshing the store (the read function in the example from the above link). The check for (isLocal) is always called even if i dont pass any parameter in the read function(Passing parameter "yes" if offline to check if the queue is present.). When i gave alerts, it seems to be value "OK" and hence the url which has sap.islocal appended in it is throwing error 400. To prevent this, I have right now checked if the value is "yes", the one i am passing when offline and proceeded .Is this the correct way of calling the read function??

3) currently out of the 2 stores equipmentstore and equipment store offline, only one store is being used via this offline method. When online, i clear and reload this and when offline I read from it. Is there a need of 2 seperate stores for online and offline?

4) when should i use closestore and clearstore?

Almost all links i get online is based on Native development. I am using sencha touch with kapsel plugins for hybrid app development.

Kindly reply.

Accepted Solutions (1)

Accepted Solutions (1)

midhun_vp
Active Contributor
0 Kudos

Hi Pooja,

You have to go through the recording of webinar on offline by Jeff to understand offline clearly:

From your code I can see that you are clearing the offline store when the device comes back online. You should not clear the data in offline store to update the store. To update the offline store (to get new/changed records to local db) you have to use Refresh API, and to update the backend with the offline store changes (changes did in local db while device was offline, ex. created a new record) you have to call Flush API.

Whenever you need to use offline store you have to open the offline store, then applyHttpClient.

ApplyHttpClient will overrides the actual http request (ex.Odata.defaultHTTPClient of datajs) with it's own custom Odata HTTP client object, hence all the requests which are made will go to local db instead of actual http request.

Regards, Midhun

SAP Technology RIG

win_poojarahulb
Explorer
0 Kudos

Hi Midhun,

Thank you for replying. I was clearing the store because once the connection is restored,if i only used store.refresh(read,error) I was getting duplicated records. Clearing and refreshing kind of solved it. I am not sure if its correct.

I will go throught the webinar as you have mentioned .


Whenever a device has a change in network state from offline -> online, flushstore() should be called ?

and in a single definingRequest, can i mention all entitiy sets of a service ?I mean create a store once and  and then open the store to different read functions as per my requirements? or should i create different stores for each entity set of same service?

midhun_vp
Active Contributor
0 Kudos

Hi Pooja,

Refresh should not create duplicate records. You can give more information on this issue.

You have to call Flush only if you have changed any records locally and you want to update it to backend.

You can define multiple Odata collection names in a single store.

Ex.

definingRequests : {

  purcahseOrder     : "/PoSet?$expand=PODetails",

  purchaseRequisition    : "/RequisitionSet"

}

You can also create multiple stores in a single app. You can refresh/flush each store whenever needed.

Ex.

sap.OData.store[0].flush(successCallback, errorCallback);

Regards, Midhun

SAP Technology RIG

win_poojarahulb
Explorer
0 Kudos

Hi Midhun,

I tried deleting cleardata function and using only refresh function as in the code given. But I got duplicate records as in the screenshots below. Is it because I am using a single store file for both online and offline in my sencha app ?? Also, as per your last message, I have used a single offline store and used all the entitysets as defining requests in it and is calling the appropriate read function based on a flag.I am also using only a single flush method so that the data is sent back to server once device comes online. Is this a correct way? Kindly reply.


//open store success for workorder header

function openStoreSuccessCallback() {

 

    console.log("open store WO successs");

    var endTime = new Date();

    var duration = (endTime - startTime) / 1000;

    if (!store) {

        console.log("The store must be open before it can be refreshed");

        Ext.Msg.alert("Offline Store does not contain data !!");

        return;

    }

    if (navigator.onLine) {

        clearData();

        if(actioncounter == 1){

            store.refresh(read, unRegisterErrorCallback);

        }

        else if(actioncounter == 2){

            store.refresh(read_EQ, unRegisterErrorCallback);

        }

        else if(actioncounter == 3){

            store.refresh(read_onEquipmentButtonCommand, unRegisterErrorCallback);

        }

        else{

            alert("error");

        }

        flushStore();

    }

    else {

        Ext.Msg.alert( "You have gone Offline .Please verify your network connectivity.");

        sap.OData.applyHttpClient();

        var readlocal = "yes";

        if(actioncounter == 1){

            read(readlocal);

        }

        else if(actioncounter == 2){

            read_EQ(readlocal);

        }

        else if(actioncounter == 3){

            read_onEquipmentButtonCommand(readlocal);

        }

        else{

            alert("error");

        }

    }

}

midhun_vp
Active Contributor
0 Kudos

Hi Pooja

I can see that in your refresh call you are calling another Odata request (read,read_EQ etc). It should be a successcallback instead.

Ex.


function refreshStore() {

        if (!store) {

            alert("The store must be open before it can be refreshed");

            return;

        }

      

        store.refresh(refreshStoreCallback, errorCallback);

    }

   

    function refreshStoreCallback() {

        alert("Refresh success");

    }

It will refresh all the collections of offline store.

If you want to refresh only a particular collection you have to create multiple offline stores. Then do refresh of the stores separately.

Ex.


for (var i = 0; i < sap.OData.stores.length; i++) {

if (sap.OData.stores[i].name === “storename”)

{

// store

}

}

sap.OData.stores[0].flush(flush_success, flush_failure);

Hope that helps.

Regards, Midhun

SAP Technology RIG

Answers (0)