Referencing local jQuery.sap.storage initialized in onInit in other functions - sapui5

I'm attempting to use local storage to store variables used throughout a workflow. I initialize the local storage in the onInit function of my controller as shown below.
onInit: function () {
var data = {
"testItem" : [{
"priority" : 1,
"title" : "test1"
}]
}
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
this.getView().setModel(oModel, "testModel");
jQuery.sap.require("jquery.sap.storage");
var oStorage = jQuery.sap.storage(jQuery.sap.storage.Type.local);
if(oStorage.get("myLocalData")){
var oData = oStorage.get("myLocalData");
oModel.setData(oData);
}
}
Once this has been initiated it, how do I access that storage within other functions like an addItem function below?
addItem: function(evt){
var oView=this.getView();
var newItem = oView.byId("input").getValue();
var oModel = oView.getModel("testModel");
var oNew = {
testItem : {"priority" : 6, "title" :newItem }
};
var oData = oModel.getData();
oData.agendaItem.push(oNew);
oModel.refresh(true);
oStorage.put("myLocalData", oData); //this is where I'm unsure
}
Everything else (however hacky ;) ) works up to this point but I can't seem to wrap my head around accessing this local storage. Can I bind it with sap.ui.core or is it persistent in that my initial call in onInit is pointless and local storage is accessible at any point?
I appreciate your patience with me as I'm extremely new to the SAPUI5 library.

Ok so its as easy as it sounds. Using the line
jQuery.sap.storage(jQuery.sap.storage.Type.local).put("myLocalData", oData);
Puts the data in the local storage. Cheers!

Related

How to pass a key field as variable instead of hard-coded key value to OData operation?

I am calling the GetEntity OData read method from the SAP UI5 view controller and passing a key value in the request URL. I am getting the proper response from the back-end when I hardcode the key value.
However, when I try to pass the key value dynamically in a variable by appending it to the URL, it doesn't work. I get the following error
HTTP request failed 404
In below code, sGrant is the variable and it doesn't work. But if I replace the variable name with its value hard-coded in below code, for example, in the read method like this: "/GrantMasterSet('TY560003')", then it works:
var sGrant = this.byId("grantNbr").getValue();
var oMod = this.getOwnerComponent().getModel();
oMod.read("/GrantMasterSet('sGrant')", {
success: function(oData) {
var oJsonModel = new JSONModel();
oJsonModel.setData(oData);
this.getView().setModel(oJsonModel);
}.bind(this),
error: function(oError) {
MessageToast.show("Read Failed");
}
});
UI5 has a method to generate the right URI for you, no matter what is the data type of the key of your entity type.
The method is createKey of the sap.ui.model.odata.v2.ODataModel class. See its documentation
Inside your controller, use the following source code.
onInit: function () {
var oRouter = this.getOwnerComponent().getRouter();
oRouter.getRoute("routeName").attachPatternMatched( this.onPatternMatched , this );
},
onPatternMatched: function(oEvent){
var oParameters = oEvent.getParameters();
var oArguments = oParameters.arguments; // is not a function - without ()
var sKey = oArguments.id; // route parameter passed when using navTo
var oDataModel = this.getView().getModel(); // v2.ODataModel
oDataModel.metadataLoaded().then(function() {
var sPath = oDataModel.createKey("EntitySet", { Key: sKey });
this.getView().bindElement("/" + sPath);
}.bind(this)
);
}
Usually this is necessary in details pages, in order to apply element binding to a page. As the createKey method relies on the $metadata of your service, you must make sure that it is already loaded in your app. This can be achieved by using method metadataLoaded, provided in the snippet as well.
You should concatenate the variable to the rest of the string, like this:
oMod.read("/GrantMasterSet('" + sGrant + "')", {
Or, you can use a template literal, which comes down to the same thing (notice the backtics):
oMod.read(`/GrantMasterSet('${sGrant}')`, {
You should escape 'sGrant' so it can be evaluated.
It should be something like that :
var sGrant = this.byId("grantNbr").getValue();
var oMod = this.getOwnerComponent().getModel();
oMod.read("/GrantMasterSet("+sGrant+")", {
success: function(oData) {
var oJsonModel = new sap.ui.model.json.JSONModel();
oJsonModel.setData(oData);
this.getView().setModel(oJsonModel);
}.bind(this),
error: function(oError) {
MessageToast.show("Read Failed");
}
});

attachRequestCompleted errors out in init()

I am using following snippet which I am using in init function. My oAppModel is getting loaded with the data. However, oAppModel.attachRequestCompleted() does not get executed even. I have tried to pass oEvent also, but when I use oEvent, it says oEvent is not defined.
var oAppModel = new sap.ui.model.json.JSONModel();
oAppModel.loadData(oData);
//attach
oAppModel.attachRequestCompleted(function(){
//get value:
var soldto = oAppModel.getProperty("/SoldTo/0/Name");
});
Could you please help ?
you are loading data (oData) into the model hence not HTTP(s) request is made. therefore, requestCompleted event is not fired.
it will fire if you do this.
var oAppModel = new sap.ui.model.json.JSONModel();

Stubbing byId() in SAPUI5-sinon

I'm filddling with sinonjs in SAPUI5. But there are some things I can't get my head around.
QUnit.module("Validation of Betaalwijze", {
beforeEach : function () {
this.oMainViewController = new MainViewController();
this.oViewStub = new ManagedObject();
var data = {
IBANPrimair: "123",
IBANSecundair: "456",
Betaalwijze: ""
};
var oModel = new JSONModel(data);
var fakeBetaalwijzeField = new Input();
sinon.stub(this.oViewStub, "getModel").returns(oModel);
sinon.stub(this.oViewStub, "byId").returns(fakeBetaalwijzeField);
sinon.stub(this.oMainViewController, "getView").returns(this.oViewStub);
},
afterEach : function() {
this.oMainViewController.destroy();
this.oViewStub.destroy();
this.fakeBetaalwijzeField.destroy();
}
});
QUnit.test("Should set an ValueState Error", function (assert) {
// Arrange
//All preparation here above.
// Act
this.oMainViewController._validateInput();
// Assert
//TODO
});
The getModel-stub works nicely when I use a "sap/ui/base/ManagedObject" for the oViewStub. But the byId-stub causes the message "Attempted to wrap undefined property byId as function" in that case.
When I use a "sap/ui/core/mvc/View" for the oViewStub, the getModel-stub is not found. (But this gives an error in the beforeEach also: Cannot read property 'viewData' of undefined.)
What is the right way to stub the View and it's methods getModel() and byId()?
The answer is quiete simple: sap.ui.base.ManagedObject does not have a method byId. This is a method of sap.ui.core.mvc.View. Just create a View instead of a ManagedObject in beforeEach and you should be fine.
BR
Chris

JSONModel: How to merge with existing data when calling "loadData"

I have the following coding in my SAP UI5 application Controller:
var myView = this.getView();
var data1 = { "myDate": new Date() };
oModel.loadData("products.json");
oModel.setData(data1);
myView.setModel(oModel);
Where products.json - just a simple data for the table on the screen.
And I can see only products.json data on the screen as a result, and myDate with empty value inside oModel (checked in debug).
In case I comment loadData string, myDate value is on the screen and looks good.
How I can use them together? What is the best practice for such cases?
The model's loadData is an asynchronous process, so it will update the model after you have set it synchronously with data1.
Also, setData() will wipe everything already in the model, so better use setProperty and update only a specific node in your model.
You should add the static data once you have loaded it from file:
oModel.attachRequestCompleted(function() {
oModel.setProperty("/myExtraData", data1);
});
Your added date is then available via /myExtraData/myData
Merge new data with existing one with bMerge parameter of setData().
oModel.loadData("products.json");
var data1 = {
"myDate": new Date()
};
oModel.attachRequestCompleted(function() {
oModel.setData(data1, true);
});
The API loadData has also a bMerge option.
oModel.setData({ myDate: new Date() });
oModel.loadData("products.json", null, true, "GET", /*bMerge*/true);
// Merged results:
{
myDate: /*date object*/,
produces: [/*...*/]
}
No need to register an event handler for requestCompleted.

custom webapi function binding to store extjs grid

I need help to bind data returned by a custom webapi function. Say my webapi function calling syntax is like below:
var filter = {<some conditions here>};
Myapp.systemcontroller.Getdata(filter).then(function(result){
--- this result contain my data and total record
});
How can I bind this function to the store proxy and then bind it to a grid?
Any help would be greatly appreciated.
You can use different way to add the data to store. Its depend on your data structure(array or object).
grid.getStore.add(model) -ref:
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store
grid.getStore.loadData(data,[append]) - ref:
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-method-loadData
grid.getStore.loadRawData(data,[append]) - ref:
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-method-loadRawData
grid.getStore.loadRecords(records,options) - ref:
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-method-loadRecords
In your case, you can use loadRecords() or add()
The problem has been fixed. I m not using any proxy in my store.. I m using the above api to retrieve the data and bind it to store using loadData method. Then I will set the totalProperty of my toolbar as well
-- on load
Myapp.systemcontroller.Getdata(f).then(function (data) {
gridstore.loadData(data.Items);
gridstore.totalCount = data.TotalNumber;
var pgTb = Ext.getCmp('DataListPgTb');
pgTb.onLoad();
me.getLogList().setLoading(false);
});
Then in the toolbarchange event
toolBarChange: function (tbar, pageData, eOpts) {
var pageSize = PrIns.getApplication().Configuration.PageSize;
var me = this;
me.getLogList().setLoading(true);
var f = Ext.create(MyApp.webapi.filter.LogFilter', { pageIndex: pageData, pageSize: pageSize, orderBy: 'Ascending' });
var gridstore = this.getLogList().getStore();
Myapp.systemcontroller.Getdata(f).then(function (data) {
gridstore.loadData(data.Items);
gridstore.totalCount = data.TotalNumber;
gridstore.currentPage = pageData;
var pgTb = Ext.getCmp('DataListPgTb');
pgTb.onLoad();
me.getLogList().setLoading(false);
});
return false;
},
return false will prevent us from calling the proxy