Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
ericci
Active Contributor
#tipoftheday will be a series of blog post that I’m mirroring from my Medium account.

Before SAPUI5 1.30 you were forced to init your JSON model inside your Component.js like this:
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel"
], function(UIComponent, JSONModel) {
"use strict";

return UIComponent.extend("com.openui5.example.Component", {

metadata: {
manifest: "json"
},

init: function() {
// call the base component's init function
UIComponent.prototype.init.apply(this, arguments);

//Create the model and load data from the local JSON file
var oModel = new JSONModel("./model/init_data.json");
oModel.setDefaultBindingMode("OneWay");

// set the device model
this.setModel(oModel, "init_data");
}
});

});

Why waste time and code when you can simply load it directly from the manifest.json?


I’ve created a stripped manifest that will show you only the interesting parts to copy/past.



{
"_version": "1.1.0",
"sap.app": {
"dataSources": {
"init_data_alias": {
"uri": "model/init_data.json",
"type": "JSON"
}
}
},
"sap.ui5": {
"_version": "1.1.0",
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "com.openui5.example.i18n.i18n"
}
},
"init_data": {
"type": "sap.ui.model.json.JSONModel",
"dataSource": "init_data_alias"
}
}
}
}


  1. Create an entry inside the sap.app dataSources with an alias name like “init_data_alias”. You must at least specify the uri of the source that can be a local path to the json file or an URL to the service. Also you can specify the type of the data (default oData)

  2. Create an entry inside the sap.ui5 models. The name used for the entry name will be the name of the model. Leave it alone if you want to replace the default component model. Now you just need to specify the type (in my case sap.ui.model.json.JSONModel) and which is the dataSource alias we used inside sap.app.dataSources


Pretty easy uh?

20 Comments
Former Member
0 Kudos

Hi Emanuele,

It was very helpful and nicely explained. Only question bothering me is if I have to add add source for OData I will do something like this

“dataSources”: {
   “localService”: {
     “uri”: “/”,
     “type”: “OData”,
     “settings”: {
       “odataVersion”: “2.0”,
       “localUri”: “localService/metadata.xml”
     }
  }

}

 

What will happen when I will add remote OData endpoints? Do I need to update manifest? can I add two data source for OData i.e for local and remote?

ericci
Active Contributor
0 Kudos
Hi @Nitin, here's a working example:
  "dataSources": {
"ODATA_NAME": {
"uri": "/sap//ODATA_NAME/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"localUri": "localService/ODATA_NAME_metadata.xml"
}
}
}

Could also please reformat your code in order to let other user read it properly?

 

Cheers, Emanuele.
michael_paonam2
Explorer
Hi @Emanuele,

I followed your article and I gave an entry in the datasources with an alias name "airline_data_alias" as follows -
	"dataSources": {
"mainService": {
"uri": "../destinations/Planner/Aviation/aviationservices.xsodata/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"localUri": "localService/metadata.xml",
"annotations": [
"annotation0"
]
}
},
"annotation0": {
"type": "ODataAnnotation",
"uri": "annotation0.xml",
"settings": {
"localUri": "annotation0.xml"
}
},
"airine_data_alias": {
"uri": "model/airlineData.json",
"type": "JSON"
}

and gave a model definition as well -
	"models" : {
"airline_data": {
"type": "sap.ui.model.json.JSONModel",
"dataSource": "airline_data_alias"
}
}

But for some reason,  I am not able to use the JSONModel when I use the alias inside the Controller -
onInit: function(){}

var localModel = new JSONModel("airline_data_alias");
localModel.attachRequestCompleted(function(){
console.log(localModel.getData());
});

}

I tried using -

var localModel = new sap.ui.model.json.JSONModel("airline_data");

 

It still didn't work.

 

It worked only when I gave the url to the JSON file -

var localModel = new sap.ui.model.json.JSONModel("model/airlineData.json");

 

Is there a way to avoid the usage of url ?

 

Regards,

Michael Paonam
ericci
Active Contributor
0 Kudos
I've not tested your code yet but I can see a typo inside your "dataSources" definition.

You typed  airine_data_alias instead of airline_data_alias. You're missing an l 😉
vk8893
Explorer
0 Kudos
How do you specify the mode of binding (OneWay/TwoWay) inside manifest file?
ericci
Active Contributor
0 Kudos
Hi Vishnu as far as I can see it is possible to do that.

This is the documentation about manifest.json (really poor). Take a look at the "models" section. You have to use the settings attribute that will pass all the object configuration to the ODataModel constructor.

I've not personally tested it but you can go with something like this:

 
"your_model_name": {
"type": "sap.ui.model.odata.ODataModel",
"dataSource": "your_manifest_datasource",
"settings": {
"defaultBindingMode": "TwoWay"
}
},
vk8893
Explorer
Hi Ricci, Thank you for the reply. I have tried this but this is not setting up the model. By default, I could see the model is TwoWay in debugger. In manifest, i want to set it to OneWay, but not happening. Any other leads?
michael_smithe5
Participant
0 Kudos
Emanuele,

Great post.  Thank you for sharing.  I do have a question though: What if I want to temporarily provide the app server (protocol, hostname, port) for the odata service while testing on my local machine?  Is there a simple way to do that (other than hard-coding it with the uri in the manifest.json, then removing later before I deploy to the server)?

Thanks,

Michael Smith
garreth_kelly
Explorer
0 Kudos
At what point does the model become available ,

i downloaded the sample shop administration app from :

https://openui5nightly.hana.ondemand.com/#/demoapps

Sample app is:

https://openui5nightly.hana.ondemand.com/test-resources/sap/tnt/demokit/toolpageapp/webapp/index.htm...

 

in the App.controller.js i tried the following in the init() function

var oBundle = this.getModel("i18n").getResourceBundle();

However in the console it returns :

Cannot read property 'getResourceBundle' of undefined

Manifest does have :
"models": { "models": {  "i18n": { "type": "sap.ui.model.resource.ResourceModel", "settings": {  "bundleName": "sap.ui.demo.toolpageapp.i18n.i18n" }  }

 

and Component.js has
metadata: { metadata: { manifest: "json" }

kind regards,

Garreth.
ericci
Active Contributor
0 Kudos
Hi Garreth,

 

as far as I can see Component and Controllers are loaded async and in parallel.

This means that it could happen that in the onInit of the main controller all models loaded from the manifest could still be undefined/null.

In the other hands, if your data binding is still done in the xml you should not have any problem because those bindings are refreshed when the data model is updated.
Narender1
Explorer
0 Kudos
Hi ericci

I am getting a 404(Not Found) error. i followed the below steps.

 

  1. changes in Manifest.json file

    1. defined a model under models section




 
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "test.i18n.i18n"
}
},
"image": {
"type": "sap.ui.model.json.JSONModel",
"dataSource": "image"
},
"personData":{
"type": "sap.ui.model.json.JSONModel",
"dataSource": "personData_alias"
}
},

 

2. defined the datasource under dataSources section
"personData_alias":{
"uri": "model/personData.json",
"type": "JSON"
}

 

3. created a new json file in model folder with name "personData.json"

4. tried to access the model using
var oPersonDataModel = new JSONModel("personData_alis");
var name = oPersonDataModel .getProperty("name");

i dont get any error (like undefined) in accessing oPersonDataModel variable but i can not see any property that i have defined in personData.json file. The console shows error 404 (Not Found) for personData_alis.

Could you please help
Vlad
Advisor
Advisor
I know this is late. I have debugged the standard code and found out the following chain. Since the "binding type" is a part of sap.ui.model.Model, its constructor ignores settings from manifest.json:
var Model = MessageProcessor.extend("sap.ui.model.Model",  {
constructor : function () {
MessageProcessor.apply(this, arguments);

...
this.sDefaultBindingMode = BindingMode.TwoWay;
this.mSupportedBindingModes = {"OneWay": true, "TwoWay": true, "OneTime": true};
...
},

The constructor doesn't accept any arguments and thus, the defaultBindingMode property is always TwoWay.

By the way, you should not use "settings" in manifest.json for JSONModel, because it isn't "settings", it is "bObserve" (new sap.ui.model.json.JSONModel(oData, bObserve)). The funny fact is that you cannot define "bObserve" in the "settings", because the manifest.json processing code is written for OData models only. JSON or other models are handled so-so.


I have to admit, that there is no way to work with two-way binding (or other properties) in manifest.json, if you do not use ODataModel. Some settings are propagated to ODataModel, but for other models everything is lost.
0 Kudos
Hi Vladislav,

I find your reply very helpful. I've also noticed, that if I set some Model attribute in onInit event, it will be overwritten. Do you know the way to redefine Constructor of the Model?

 
Vlad
Advisor
Advisor
0 Kudos
Oh, I haven't noticed your question. Sorry.

Indeed, I do not know a better way to override the constructor rather than to inherit the class and implement your changes there.

I have two ideas 🙂

The first one is to use events from ComponentContainer, e.g. componentCreated or init and override the model properties there,

or the second one is to set the breakpoint in the default constructor and check via the stack from which part of the application lifecycle it is called. Maybe few lines down, you can change the required properties.
Dheerendra
Participant
0 Kudos
Nice blog ..well explained for new person in this area like me..The only point which Michael pointed out ....i also tried and it only worked when we gave the URL to json file....why?

Thanks

Dheer

 
ericci
Active Contributor
0 Kudos
Hi Narender, you can have a look at a demo code here (how to define model/data source in manifest JSON and how to use it inside your view/controller): https://github.com/StErMi/openui5-swissknife/tree/master/test/demo-1-49

 

Anyway, as far as I can see from your example, you don't need to create the JSONModel like you did in point 4. Manifest handle the creation for you. So in your controller you already have a JSONModel created and you can access it via
this.getView().getModel("personData").getProperty("/name");

 
ericci
Active Contributor
0 Kudos
Hi Dheerendra, here you have a full working example that uses JSONModel from manifest.json: https://github.com/StErMi/openui5-swissknife/tree/master/test/demo-1-49

Can you provide me an example code? Maybe I can give an hint to it.
Former Member
0 Kudos
Thanks ericci 🙂
Dheerendra
Participant
0 Kudos
Thank you very much Ricci.
0 Kudos

Hi Ricci,


Really very one of the nice blog. Thanks for sharing with us. I have used in my one of the requirement. It's working but if I want to do multiple time then there is failure.


Do you have any insight how to achieve this? Sorry to asking question here as could not find any help document any where.


I have to show same kind of information on click of 3 separate Generic tiles in sap ui5. On click of first time need to show title, image and description similarly for the other tiles as well same field but data would be different. It is JSON model and I have prepared json file in default model same json file path has been defined. I can access data in case of first tile click but in other cases getting below error. I have used manifest.json configuration no controller code here. Error : "Assertion failed: list bindings support only a single template object" manifest.json code : "dataSources": { "init_data": { "uri": "model/data.json", "type": "JSON" } } "": { "type": "sap.ui.model.json.JSONModel", "dataSource": "init_data" } Json file structure : { "hrAppCollection": [{ "Heading": "TimeSheet Entry app", "AppPicUrl": "./image/timesheet.jpg", "PlaceHolderText": "Approval of Firefighter Access Request submitted for Production system instances." }, { "Heading": "Approve Firefighter Request", "AppPicUrl": "./image/timesheet.jpg", "PlaceHolderText": "Approval of Firefighter Access Request submitted for Production system instances." }] } I have tried using named model concept and did some json file data manipulation but I am not able to figure out how to achieve this. Let me know if you need any further information on the same.


BR,


RK

Labels in this area