I want to create a array structure with child entities like this ->
$scope.groups = [
{
"categories": [
{
"name": "PR",
"sortOrder": 0,
"type": "category"
}
],
"name": "DEPT 1",
"sortOrder": 0,
"type": "group",
"id": "-JY_1unVDQ5XKTK87DjN",
"editing": false
}
];
from an array that dosen't have child entities but all the items are listed in one object like this->
$scope.groups = [
{
"name": "PR",
"sortOrder": 0,
"type": "category"
},
{
"name": "AD",
"sortOrder": 3,
"type": "category"
},
{
"name": "DEPT 2",
"sortOrder": 1,
"type": "group",
"id": "-JYZomQKCVseJmaZoIF9",
"editing": false,
"categories": []
},
];
Is there any possible way?
As #Eagle1 has rightly pointed out. You need to define your data model properly to define a function that does that grouping for you. That said, from what I understand you have a $scope.groups array of objects for a specific department containing some categories which you need to consolidate as a child element.
You could start by defining a function that returns an object like you mention:
var organize = function(arr){
cats = [];
dep = {};
$.each( arr, function( i, val ) {
if(val.type == "category")
cats.push(val);
else
dep = val;
});
dep.categories = cats;
return dep;
}
Ultimately, you'll have to traverse the array and look for objects of type category and dump them in an array and have that array as the categories key of the object that you intend to return. I hope it gets you started in the right direction.
of course it is.
It's doable in javascipt although to help you devise something we would need a relationship between categories.
However, that's sounds like something that should be done in your data model (a relationship between dept - category, classic reflexive relationship parent - children). angular should be receiving from the back end an array already ordered.
Related
Hi I am having difficulty in traversing in javascript object. How can I get scheme_name & NAV from both and store it in variable like "You have 2 schemes linked to your account. scheme_name1 NAV value is "" scheme_name2 NAV value is "" and so forth. Please explain it to me thanx
let data = [{
"CustomerID": 12345,
"NAV": "95.24059718",
"cost_of_purchase": 799900,
"folio_number": 10007060,
"id": 1,
"mutual_fund_house": "AXIS MUTUAL FUND",
"no_of_units": 15000,
"option": "GROWTH",
"plan": "REGULAR",
"resource_uri": "/api/v1/folio/1/",
"scheme_name": "AXIS LONG TERM EQUITY",
"value_of_units": "1428608.9580"
}, {
"CustomerID": 12345,
"NAV": "1053.31517400",
"cost_of_purchase": 1500000,
"folio_number": 5540000567,
"id": 2,
"mutual_fund_house": "SBI Mutual Fund",
"no_of_units": 2750,
"option": "DIVIDEND",
"plan": "DIRECT",
"resource_uri": "/api/v1/folio/2/",
"scheme_name": "SBI Magnum Multicap Fund",
"value_of_units": "2896616.7270"
}]
It looks like you try to map that object to another object.
First, try to read and understand array methods, you can check:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
And for map method you can check:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
And as a specific answer you can do:
const mappedData = data.map(function(item) {
return {
scheme_name: item.scheme_name,
NAV: item.NAV
};
});
This will return you an array of a simplified version of yours.
After that, you can convert it to a string like:
let solution = `You have ${mappedData.length} schemes linked to your account. `;
mappedData.forEach(function(mapped) {
solution += mapped.scheme_name + ' is ' + mapped.NAV + ' '
});
Note: I showed map method for giving an insight about what you can do, normally you don't need to simplify, you can directly use for each version.
Imagine each one of your objects (in this case you have provided two (2)) as an associative array inside of an array. Meaning that rather than reference it by it's index position, you can reference it by it's key.
This means to access object 1, you would have to write data[0]. But if you alerted this, this would simply tell you that data[0] is an object. Which is is.
To access an actual value in that array, you would then have to provide the key, which you can do by providing a number, or in your case perhaps more easily, it's associated key, which is "scheme_name".
See the following :
let data = [{
"CustomerID": 12345,
"NAV": "95.24059718",
"cost_of_purchase": 799900,
"folio_number": 10007060,
"id": 1,
"mutual_fund_house": "AXIS MUTUAL FUND",
"no_of_units": 15000,
"option": "GROWTH",
"plan": "REGULAR",
"resource_uri": "/api/v1/folio/1/",
"scheme_name": "AXIS LONG TERM EQUITY",
"value_of_units": "1428608.9580"
}, {
"CustomerID": 12345,
"NAV": "1053.31517400",
"cost_of_purchase": 1500000,
"folio_number": 5540000567,
"id": 2,
"mutual_fund_house": "SBI Mutual Fund",
"no_of_units": 2750,
"option": "DIVIDEND",
"plan": "DIRECT",
"resource_uri": "/api/v1/folio/2/",
"scheme_name": "SBI Magnum Multicap Fund",
"value_of_units": "2896616.7270"
}]
for (let i = 0; i < data.length; i++) {
alert(data[i]["scheme_name"]);
}
So quite simply, for i = 0, with i being less than the number of associative arrays in your array named data, alert the value on that indexed array, by the associated key.
You've got an array of data so firstly you need to iterate through that array.
Pick which properties you want to keep per record, and save them to a results array.
Once you have the results you can iterate through them and print out your individual records.
let data = [{"CustomerID":12345,"NAV":"95.24059718","cost_of_purchase":799900,"folio_number":10007060,"id":1,"mutual_fund_house":"AXIS MUTUAL FUND","no_of_units":15000,"option":"GROWTH","plan":"REGULAR","resource_uri":"/api/v1/folio/1/","scheme_name":"AXIS LONG TERM EQUITY","value_of_units":"1428608.9580"},{"CustomerID":12345,"NAV":"1053.31517400","cost_of_purchase":1500000,"folio_number":5540000567,"id":2,"mutual_fund_house":"SBI Mutual Fund","no_of_units":2750,"option":"DIVIDEND","plan":"DIRECT","resource_uri":"/api/v1/folio/2/","scheme_name":"SBI Magnum Multicap Fund","value_of_units":"2896616.7270"}]
let results = []
data.forEach(datum => {
results.push({
scheme_name: datum.scheme_name,
nav: datum.NAV,
})
})
console.log(`You've got ${results.length} items in your account.`)
results.forEach(result => {
console.log(`${result.scheme_name} - NAV value is: ${result.nav}`)
})
I created sample fiddle for you. You need to iterate over each object in your main object and store all information outside.
data.forEach(function(item) {
console.log(item.scheme_name);
});
I want to create a JSON API that returns a list of objects. Each object has an id, a name and some other information. API is consumed using JavaScript.
The natural options for my JSON output seems to be:
"myList": [
{
"id": 1,
"name": "object1",
"details": {}
},
{
"id": 2,
"name": "object2",
"details": {}
},
{
"id": 3,
"name": "object3",
"details": {}
},
]
Now let's imagine that I use my API to get all the objects but want to first do something with id2 then something else with id1 and id3.
Then I may be interested to be able to directly get the object for a specific id:
"myList": {
"1": {
"name": "object1",
"details": {}
},
"2": {
"name": "object2",
"details": {}
},
"3": {
"name": "object3",
"details": {}
},
}
This second option may be less natural when somewhere else in the code I want to simply loop through all the elements.
Is there a good practice for these use cases when the API is used for both looping through all elements and sometime using specific elements only (without doing a dedicated call for each element)?
In your example you've changed the ID value from 1 to id1. This would make operating on the data a bit annoying, because you have to add and remove id all the time.
If you didn't do that, and you were relying on the sorted order of the object, you may be in for a surprise, depending on JS engine:
var source = JSON.stringify({z: "first", a: "second", 0: "third"});
var parsed = JSON.parse(source);
console.log(Object.keys(parsed));
// ["0", "z", "a"]
My experience is to work with arrays on the transport layer and index the data (i.e. convert array to map) when required.
Can I create an object dynamically from JSON?
This is one of some in array:
values: [{
"$type": "Entrance, DataModel",
"EntranceDeviceData": {
"$type": "DeviceData, DataModel",
"Watchdog": 0,
"Inputs": {
"$type": "Int16[], mscorlib",
"$values": [0, 0]
},
"Outputs": {
"$type": "Int16[], mscorlib",
"$values": [0, 0]
},
"Faults": {
"$type": "Int16[], mscorlib",
"$values": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
},
"StandingCommand": 0
},
"Vehicle": null,
"NextStates": {
"$type": "System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib",
"$values": ["CarApproachingBarrier"]
},
"Repository": {
"$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"
},
"Direction": 0,
"Name": "Entrance",
"Position": "0,0,0,0",
}, {...another object...
}, {...another one...
}
]
This both JSON objects are different. Can I create an object (for every other JSON object) without knowing in advance it's properties? How can I do it?
(I heard something that it possible, but maybe I didn't understand well the person who said that).
What you gave as examples of JSON in your original code above is Javascript's way of defining literal objects. json1 and json2 already ARE javascript objects, no need to create them.
// original code from question
var json1 = {
"mysex": "female",
"yoursex": "male",
"location": {
"lat": "48",
"lng": "1"
},
"description": "descr2",
"owner": "zBYnfuu8DXEwMttwZ",
"nickname": "user",
"_id": "1"
};
As nnnnnn pointed out below JSON is most commonly used to refer to a STRING containing code formatted as above, that would be:
var json1_as_string = '{
"mysex": "female",
"yoursex": "male",
"location": {
"lat": "48",
"lng": "1"
},
"description": "descr2",
"owner": "zBYnfuu8DXEwMttwZ",
"nickname": "user",
"_id": "1"
}';
To get from such a String to an actual Javascript Object you would need to parse it:
var json1 = JSON.parse(json1_as_string);
the opposite direction (Javascript Object to String) is achieved by stringify:
var json1_as_string = JSON.stringify(json1);
see https://developer.mozilla.org/en-US/docs/Using_native_JSON
p.s.
It does seem strange that these two very different objects have the same "_id".
You've changed the question completely, and I'm trying to understand what you are asking.
This both JSON objects are different. Can I create an object (for
every other JSON object) without knowing in advance it's properties?
How can I do it?
Yes, in Javascript you can create objects without knowing their properties in advance. Javascript is not strongly typed, and it has no classes. So there's absolutely no problem
with having objects with different properties.
I'm having trouble finding a solution that will help me loop through a bunch of elements and putting the chosen values into a table. I've been able to withdraw some values but the method isn't dynamic.
Here is an example:
var Table = {
"credit": {
"link": "site link",
"logoUrl": "logo url",
"message": "message"
},
"groups": [
{
"labels": [
{
"name": "Western Conference",
"type": "conference"
},
{
"name": "Central Division",
"type": "division"
}
],
"standings": [
{
"stats": [
{
"name": "gp",
"value": 20
},
{
"name": "w",
"value": 17
},
{
"name": "l",
"value": 0
},
{
"name": "gf",
"value": 64
},
{
"name": "ga",
"value": 37
},
{
"name": "gd",
"value": 27
},
{
"name": "pts",
"value": 37
}
],
"team": {
"id": 12345,
"link": "team link",
"name": "team name",
"shortName": "team"
}
},
This is the structure of the elements. So far I've used this:
document.getElementById("sGamesPlayed").innerHTML=Table.groups[0].standings[0].stats[0].value;
to withdraw values. However there are more teams, stats and divisions so I would need some kind of loop to go through the elements and put the into a dynamic table.
I would consider you to look at http://underscorejs.org/.
it provides a bunch of utility functions that could help you,
for example, _.each() helps you loop through JSON properties.
for the sample objects you've given (after completing the missing brackets at the end),
_.each(Table.groups[0].standings[0].stats, function(stats){
console.log(stats['name']+","+stats['value'])
})
gives me:
gp,20
w,17
l,0
gf,64
ga,37
gd,27
pts,37
how it works is that you provide the object you want as the first argument and the function that you give as the second argument will be called with each element of the first argument (Assuming it is a list).
I would also urge you to look at underscore templating that you can use to render your table where i put the console.log :
http://net.tutsplus.com/tutorials/javascript-ajax/getting-cozy-with-underscore-js/
http://scriptble.com/2011/01/28/underscore-js-templates/
I guess your question is about filtering the values of the array standings. In order to do that you can use the jQuery grep function (if you want to use jQuery).
For example you can write:
var arr = $.grep(Table.groups[0].standings[0].stats, function(d){return d.value>25})
Which will give
arr = [{"name": "gf","value": 64}, {"name": "ga", "value": 37},{"name": "gd", "value": 27},{"name": "pts", "value": 37}]
If this is not what you meant, can you please create a jsFiddle with a sample of what you want?
Depending on what you want to do with the results, you can go over the object using a scheme like:
var groups, standings, stats, value;
groups = Table.groups;
// Do stuff with groups
for (var i=0, iLen=groups.length; i<iLen; i++) {
standings = groups[i].standings;
// Do stuff with standings
for (var j=0, jLen=standings.length; j<jLen; j++) {
stats = standings[j];
// Do stuff with stats
for (var k=0, kLen=stats.length; k<kLen; k++) {
value = stats[k].value;
// Do stuff with value
}
}
}
Of course I have no idea what the data is for, what the overall structure is or how you want to present it. But if you have deeply nested data, all you can do is dig into it. You might be able to write a recursive function, but it might also become very difficult to maintain if the data structure is complex.
How can I trim everything from my JSON except for a few properties I specify at different levels, while keeping my node structure and array structure?
I've looked into Underscore.js and it seems like it doesn't have as much fine-grained control for preserving the node structure. In the example below, ideally, I would like to be able to specify '_id', 'revisions[0]._id', 'revisions[0]._clientHasViewed' as arguments to keep those properties.
Surely there's an easy way to do this. Here's what I'm looking for:
ORIGINAL
{
"_id": "50cbf5214ffaee8f0400000a",
"_user": "50b1a966c12ef0c426000007",
"expenses": [],
"name": "Untitled Project",
"payments": [],
"revisions": [
{
"_id": "50cbfae65c9d160506000007",
"clientHasViewed": false,
"comments": [],
"dateCreated": "2012-12-15T04:21:58.605Z"
},
{
"_id": "50cbfae65c9d160506000008",
"clientHasViewed": false,
"comments": [],
"dateCreated": "2012-12-15T04:21:58.605Z"
}
],
"status": "Revised",
"thumbURL": "/50cd3107845d90ab28000007/thumb.jpg"
}
TRIMMED
{
"_id": "50cbf5214ffaee8f0400000a",
"revisions": [
{
"_id": "50cbfae65c9d160506000007",
"clientHasViewed": false,
},
],
}
ExtJs has a copyTo function (only one level), but you could create something similar with AngularJs (angular has angular.copy, but that copies the whole object):
var copyTo = function(dest, source, names){
names = names.split(/[,;\s]/);
angular.forEach(names, function(name){
if(source.hasOwnProperty(name)){
dest[name] = source[name];
}
});
return dest;
};
E.g.
var trimmed = copyTo({}, original, '_id,');
trimmed.revisions = [{}];
trimmed = copyTo(trimmed.revisions[0], original.revisions[0], '_id,_clientHasViewed,');