How can I loop JsonModel in sapui5? - json

I'm making my first app in sapui5.
I want create a login page with sign up and login.
In sing up I want save user name and password in a external JSON. How I can export the JSON Data?
In login I want validate password and username but i don't know how to loop the JsonModel.
I try this but of course didn't work.
var acountsJson = sap.ui.getCore().getModel("acountsModel");
for(var i = 0; i < acountsJson.length; i++) {
var obj = acountsJson[i];
console.log(acountsJson.id);
}
Can sap.ui.core has multiple Models?

Can sap.ui.core has multiple Models?
Yes, UI5-Core can hold multiple data models. In your case the model is named "acountsModel". You can add more models with different names.
Once you access your model, by sap.ui.getCore().getModel("acountsModel").getProperty("/"); you can either loop through an array using native for() or using jQuery:
$.each(acountsJson, function(value, index, array){
console.log(value.id);
});
Personally, I like the jQuery approach much more than the for-loop.

To get the JSON, you need to access your JSON Property, e.g. "/" for top node ...
var acountsJson = sap.ui.getCore().getModel("acountsModel").getProperty("/");
for(var i = 0; i < acountsJson.length; i++) {
var obj = acountsJson[i];
console.log(acountsJson[i].id);
}

Related

Is there a better way to get data from localStorage after storing the data without refreshing/reloading the page

I'm trying to make a button that could store the data to the localStorage. After storing the data, I want to get the data without refreshing/reloading the page
The way I use to fix this case is, I put 2 commands on a button. The first command is to store the data, and the second command is to get the data using $scope to make it easy to display it on the page
Here is my code
$scope.storeData = function(){
if(localStorage.getItem('value') === null){
// The value that will set to the localStorage
$scope.data = 'Selamat sore';
// To set the value on $scope.data to localStorage
localStorage.setItem('value', JSON.stringify($scope.data));
//To get the value and display it on the page
$scope.getData = JSON.parse(localStorage.getItem('value'));
}else{
$scope.getData = JSON.parse(localStorage.getItem('value'));
}
}
It's actually working, but maybe there is a better way to do this
Thanks
I find this cleaner, and simpler.
function MyController($scope) {
// if value is null a default 'Selamat sore' is set
$scope.data = localStorage.getItem('value') || 'Selamat sore';
$scope.saveData = function() {
localStorage.setItem('value', JSON.stringify($scope.data));
}
}

Getting selected elements properties in forge viewer when more then one model loaded

I have have a viewer app with 8 models loaded
I have a plugin looking for the "AGGREGATE_SELECTION_CHANGED_EVENT" event
this.viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, this.onSelectionBinded);
I need to be able to get access to the selected elements properties
this.viewer.getProperties(_dbId, (result) => { })
but it seams the viewer is only looking at the last loaded model not all of them.
do i have to load/switch to the other models ? and if so how.
The viewer.model is always pointed to the first loaded model with my experience. If you want to access other loaded models, you can obtain them via calling viewer.impl.modelQueue().getModels(). Afterward, call Viewer properties APIs in this way:
var allModels = viewer.impl.modelQueue().getModels();
var model = allModels[1];
model.getProperties( dbId, onSuccessCallback, onErrorCallback );
Besides, you can obtain the model instance in the function argument event of your onSelectionBinded callback. So, your onSelectionBinded can be modified to this based on the above logic:
this.onSelectionBinded = function( event ) {
var selSet = event.selections;
var firstSel = selSet[0];
var model = firstSel.model;
var dbIds = firstSel.dbIdArray;
var firstDbId = dbIds[0];
model.getProperties( firstDbId, onSuccessCallback, onErrorCallback );
}
Hope it helps!
I know this is a little late...
Another way to get properties for multi-model, is to use the aggregated method.
var DBids = viewer.impl.selector.getAggregateSelection();
I have a blog post and sample website that goes through the details:
https://forge.autodesk.com/blog/highlighting-clashes-multi-model

i am not able to iterate a json document in angular2

i have just started angular2, and got a problem. I am not able to iterate a json document in angular2.data is coming from backend i tried many ways, also used elipses (?) operator but not working for me. Please help
i want to print name under area array
in your .ts code, try the following:
ngOnInit() {
for(let i = 0; i < this.country.length; i++) {
for(let n = 0; n < this.country[i].area.length; n++) {
console.log(this.country[i].area[n].name);
}
}
}
You should get a list of all the names in the console
First get the json as a string; then simply call JSON.parse(myJsonString) and you have your json-object
If you meant anything else please clarify, as I (and obviously others too) don't find your question formualted 100% clearly (for example, add some code or what you have tried before)

Can I use i18n resource bundle within json data?

I have an SAPUI5 (V1.24) master-detail application wherein I have to display a list of about 25 static items and each item displays a static image when clicked.
I have the list titles stored in an i18n file which is instantiated as a ResourceBundle within the Component.js file.
Now instead of adding 25 rows of StandardListItem objects in my Master.xml.view file I was wondering if I could store all titles in a JSON file under mockdata folder and bind a JSONModel to my sap.m.List. But since the values in my JSON "key":"value"are nothing but the list titles I was looking for a way to bind the i18n texts with the JSON. Something like this:
{
"List": [
{
"Key": "'{i18n>value1}'"
},
{
"Key": "'{i18n>value2}'"
},
...
]
}
But it didn't work at runtime. Instead it displayed the value as-is, as shown below:
Adding as many list items in the view doesn't feel right. What if tomorrow the list increases from 25 to 50? Please help.
Thanks.
After our chat discussion I came up with the following solution
var aAllKeys = [],
aMasterKeys = [],
oProperties = {},
oJSON = {
items: []
};
// Get the current locale (for example "de-DE")
var sCurrentLocale = sap.ui.getCore().getConfiguration().getLanguage();
// This creates an array of locale fallback solutions.
// For example ["de-DE", "de", "en", ""]
var aFallbacks = jQuery.sap.resources._getFallbackLocales(sCurrentLocale);
// iterate all locales
for (var i = 0; i < aFallbacks.length; ++i) {
var sLocale = aFallbacks[i];
// try to load i18n file for each locale
oProperties = jQuery.sap.properties({
url: "i18n/i18n" + (sLocale ? "_" + sLocale : "") + ".properties"
});
// if the i18n file exists (i. e. contains keys)
if (oProperties.getKeys().length > 0) {
aAllKeys = oProperties.getKeys();
break;
}
}
// find all keys of items to display in master (the prefixed ones)
for (i = 0; i < aAllKeys.length; ++i) {
if (aAllKeys[i].indexOf("MyPrefix.") > -1) {
aMasterKeys.push(aAllKeys[i]);
}
}
// find all values of items to display in master
for (i = 0; i < aMasterKeys.length; ++i) {
oJSON.items.push({
key: aMasterKeys[i],
value: oProperties.getProperty(aMasterKeys[i])
});
}
You can then use oJSON to create a new JSON model which can be bound to your masterlist
Edit: I modified the beginning of the snippet. This adds a fallback solution if there is no i18n file for the current locale. This is tested against SAPUI5 v1.30.
See the solution I have provided in a similar topic: How is localized data binding set up with JSON files and XML views?
The best part, it requires only a single-line helper method :-)

Looping through JSON with node.js

I have a JSON file which I need to iterate over, as shown below...
{
"device_id": "8020",
"data": [{
"Timestamp": "04-29-11 05:22:39 pm",
"Start_Value": 0.02,
"Abstract": 18.60,
"Editor": 65.20
}, {
"Timestamp": "04-29-11 04:22:39 pm",
"End_Value": 22.22,
"Text": 8.65,
"Common": 1.10,
"Editable": "true",
"Insert": 6.0
}]
}
The keys in data will not always be the same (i've just used examples, there are 20 different keys), and as such, I cannot set up my script to statically reference them to get the values.
Otherwise I could state
var value1 = json.data.Timestamp;
var value2 = json.data.Start_Value;
var value3 = json.data.Abstract;
etc
In the past i've used a simple foreach loop on the data node...
foreach ($json->data as $key => $val) {
switch($key) {
case 'Timestamp':
//do this;
case: 'Start_Value':
//do this
}
}
But don't want to block the script. Any ideas?
You can iterate through JavaScript objects this way:
for(var attributename in myobject){
console.log(attributename+": "+myobject[attributename]);
}
myobject could be your json.data
I would recommend taking advantage of the fact that nodeJS will always be ES5. Remember this isn't the browser folks you can depend on the language's implementation on being stable. That said I would recommend against ever using a for-in loop in nodeJS, unless you really want to do deep recursion up the prototype chain. For simple, traditional looping I would recommend making good use of Object.keys method, in ES5. If you view the following JSPerf test, especially if you use Chrome (since it has the same engine as nodeJS), you will get a rough idea of how much more performant using this method is than using a for-in loop (roughly 10 times faster). Here's a sample of the code:
var keys = Object.keys( obj );
for( var i = 0,length = keys.length; i < length; i++ ) {
obj[ keys[ i ] ];
}
You may also want to use hasOwnProperty in the loop.
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
switch (prop) {
// obj[prop] has the value
}
}
}
node.js is single-threaded which means your script will block whether you want it or not. Remember that V8 (Google's Javascript engine that node.js uses) compiles Javascript into machine code which means that most basic operations are really fast and looping through an object with 100 keys would probably take a couple of nanoseconds?
However, if you do a lot more inside the loop and you don't want it to block right now, you could do something like this
switch (prop) {
case 'Timestamp':
setTimeout(function() { ... }, 5);
break;
case 'Start_Value':
setTimeout(function() { ... }, 10);
break;
}
If your loop is doing some very CPU intensive work, you will need to spawn a child process to do that work or use web workers.
If you want to avoid blocking, which is only necessary for very large loops, then wrap the contents of your loop in a function called like this: process.nextTick(function(){<contents of loop>}), which will defer execution until the next tick, giving an opportunity for pending calls from other asynchronous functions to be processed.
My most preferred way is,
var objectKeysArray = Object.keys(yourJsonObj)
objectKeysArray.forEach(function(objKey) {
var objValue = yourJsonObj[objKey]
})
If we are using nodeJS, we should definitely take advantage of different libraries it provides. Inbuilt functions like each(), map(), reduce() and many more from underscoreJS reduces our efforts. Here's a sample
var _=require("underscore");
var fs=require("fs");
var jsonObject=JSON.parse(fs.readFileSync('YourJson.json', 'utf8'));
_.map( jsonObject, function(content) {
_.map(content,function(data){
if(data.Timestamp)
console.log(data.Timestamp)
})
})
A little late but I believe some further clarification is given below.
You can iterate through a JSON array with a simple loop as well, like:
for(var i = 0; i < jsonArray.length; i++)
{
console.log(jsonArray[i].attributename);
}
If you have a JSON object and you want to loop through all of its inner objects, then you first need to get all the keys in an array and loop through the keys to retrieve objects using the key names, like:
var keys = Object.keys(jsonObject);
for(var i = 0; i < keys.length; i++)
{
var key = keys[i];
console.log(jsonObject.key.attributename);
}
Not sure if it helps, but it looks like there might be a library for async iteration in node hosted here:https://github.com/caolan/async
Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Although originally designed for use with node.js, it can also be used directly in the browser.
Async provides around 20 functions that include the usual 'functional' suspects (map, reduce, filter, forEach…) as well as some common patterns for asynchronous control flow (parallel, series, waterfall…). All these functions assume you follow the node.js convention of providing a single callback as the last argument of your async function.
Take a look at Traverse. It will recursively walk an object tree for you and at every node you have a number of different objects you can access - key of current node, value of current node, parent of current node, full key path of current node, etc. https://github.com/substack/js-traverse. I've used it to good effect on objects that I wanted to scrub circular references to and when I need to do a deep clone while transforming various data bits. Here's some code pulled form their samples to give you a flavor of what it can do.
var id = 54;
var callbacks = {};
var obj = { moo : function () {}, foo : [2,3,4, function () {}] };
var scrubbed = traverse(obj).map(function (x) {
if (typeof x === 'function') {
callbacks[id] = { id : id, f : x, path : this.path };
this.update('[Function]');
id++;
}
});
console.dir(scrubbed);
console.dir(callbacks);