Access json data from angularjs - javascript

Here is my JSON file:
{
"countries":[
{
"country": "India",
"cities" : [{
"name": "Bangalore",
"rank": "40"
},
{ "name": "Mumbai",
"rank": "32"
},
{ "name": "Kolkata",
"rank": "54"
},
{ "name": "Chennai",
"rank": "42"
}]
},
{ "country": "China",
"cities":[{"name": "Guangzhou",
"rank": "111"
},
{ "name": "Fuzhou",
"rank": "21"
},
{ "name": "Beijing",
"rank": "90"
},
{ "name": "Baotou",
"rank": "23"
}]
}
]}
This is the angularjs code:
$scope.countryType = [
{ type: 'India', data:$scope.India, displayName:'India' },
{ type: 'China', data:$scope.China, displayName:'China'},
{ type: 'Ethiopia', data:$scope.Ethiopia, displayName:'Ethiopia'},
{ type: 'Cuba', data:$scope.Cuba, displayName:'Cuba'}
];
This angularjs code is fine for me but I don't know how to access name and rank from this data of countryType and I also want to filter it according to country.
For HTML page I am using this code :
<select ng-model="country.city" ng-options="country as country.type for country in countryType | orderBy: 'type'">
<option value=""> - Select a Country - </option>
</select>
<ul ng-repeat = "city in countryType | filter : country.city.data.cities.country ">
<li ng-repeat="details in city.data.cities">
<span> {{details.name}} </span>
<span> {{details.rank}}</span>
</li>
</ul>
Shall I have to use different code in html for accessing the data?
All the data is coming but I am not able to filter it.

So, basically you have two level of Arrays in your data structure. And that is why you need to do loop inside the country loop to access the cities.
A bit of change in your data structure, And here in an example for your reference:
HTML:
<div class="container">
<div ng-controller="FormController as formCtrl">
<table>
<tbody ng-repeat="country in formCtrl.contryType">
<tr>
<th colspan="2">{{country.country}}</th>
</tr>
<tr ng-repeat="city in country.cities">
<td>{{city.name}}</td>
<td>{{city.rank}}</td>
</tr>
</tbody>
</table>
</div>
</div>
JavaScript:
var app = angular.module("myApp", []);
app.controller("FormController", function () {
var ctrl = this;
ctrl.contryType = [{
"country" : "India",
"cities" : [{
"name" : "Bangalore",
"rank" : "40"
}, {
"name" : "Mumbai",
"rank" : "32"
}, {
"name" : "Kolkata",
"rank" : "54"
}, {
"name" : "Chennai",
"rank" : "42"
}
]
}, {
"country" : "China",
"cities" : [{
"name" : "Guangzhou",
"rank" : "111"
}, {
"name" : "Fuzhou",
"rank" : "21"
}, {
"name" : "Beijing",
"rank" : "90"
}, {
"name" : "Baotou",
"rank" : "23"
}
]
}
];
});
angular.bootstrap(document, ['myApp']);
Working Fiddle: http://jsfiddle.net/ashishanexpert/zvcx5z38/5/

You can not access object property by value as in $scope.India. You should be using a function to retrieve the cities of the given country.
$scope.getCityList = function(country)
{
var index = arrayObjectIndexOf($scope.countries, country, ["country"]);
return $scope.countries[index].cities;
}
function arrayObjectIndexOf(myArray, searchTerm, property) {
for(var i = 0, len = myArray.length; i < len; i++) {
var value = myArray[i];
for(var j=0; j<property.length; j++)
{
value = value[property[j]];
}
if (value === searchTerm) return i;
}
return -1;
}
So finally, the Angular JS code gets :
$scope.countryType = [
{ type: 'India', data:$scope.getCityList("India"), displayName:'India' },
{ type: 'China', data:$scope.getCityList("China"), displayName:'China'},
{ type: 'Ethiopia', data:$scope.getCityList("Ethiopia"), displayName:'Ethiopia'},
{ type: 'Cuba', data:$scope.getCityList("Cuba"), displayName:'Cuba'}
];

You can loop through the list JSON and store it in an array:
$scope.countryType = [];
angular.forEach(json.countries, function(data){
$scope.countryType.push({type: data.country, data: data});
});
Demo

Well you are accessing your data in a wrong way! Without changing your JS code you can use the following code, which just access the data objects slightly different (but right) way than you did:
<ul ng-repeat = "country in countryType">
<li ng-repeat="details in country.data.cities">
<span> {{details.name}} </span>
<span> {{details.rank}}</span>
</li>
</ul>
And everything should work.

Related

how to bind nested json data into angularjs dropdown?

I have some json data related to timzone below i need to bind particular nested value into dropdown, in using angularjs, in timezone array its coming as string format i need to bind those into dropdown.
timezone.json --
{
"countries": {
"US": {
"id": "US",
"name": "United States",
"timezones": [
"America/New_York",
"America/Detroit",
]
},
"CA": {
"id": "CA",
"name": "Canada",
"timezones": [
"America/St_Johns",
"America/Halifax",
]
},
"IN": {
"id": "IN",
"name": "India",
"timezones": [
"Asia/Kolkata"
]
},
}
}
Script--
$http({
method: "GET",
url: 'timezon.json'
}).then(function mySuccess(response) {
$scope.timeZones = response.data;
}, function myError(response) {
$scope.timeZones = response.statusText;
});
HTML Content
<select class="form-control">
<option value="0">--Select Time Zones></option>
</select>
You can use the following to iterate through your object keys and populate your select.
<select class="form-control">
<option value="0">--Select Time Zones></option>
<option ng-repeat="(key, value) in data.countries" value="value.id">{{value.timezones.toString()}}</option>
</select>
Demo
First off manipulate data and then populate select
HTML
<div ng-app="app" ng-controller="Ctrl" ng-init="getTimeZones">
<h1>{{selectedTimezone}}</h1>
<select ng-model="selectedTimezone" ng-options="item for item in timezones">
</select>
</div>
JS
var app = angular.module("app", []);
app.controller('Ctrl', function($scope, $filter) {
$scope.timezones = []
$scope.data = {
"countries": {
"US": {
"id": "US",
"name": "United States",
"timezones": [
"America/New_York",
"America/Detroit",
]
},
"CA": {
"id": "CA",
"name": "Canada",
"timezones": [
"America/St_Johns",
"America/Halifax",
]
},
"IN": {
"id": "IN",
"name": "India",
"timezones": [
"Asia/Kolkata"
]
},
}
}
$scope.getTimeZones = setTimeout(function(){
// http request here after success
for (var key in $scope.data.countries) {
var timezones = $scope.data.countries[key].timezones;
timezones.unshift($scope.data.countries[key].name);
Array.prototype.push.apply($scope.timezones, timezones);
// For ES6
// $scope.timezones.push(...timezones)
}
}, 1000);
});
Demo

filter multiple checkbox angular

I am trying to filter my results on multiple checkboxes.
Here is my JSFIDDLE
How do i write dynamic ng-model for the checkboxes for the filter to take reflect?
function MainCtrl($scope) {
$scope.languages = [
{ name: 'persian', _id : 0 },
{ name: 'English', _id : 1 },
{ name: 'spanish', _id : 2 }
];
$scope.bu = [
{ name: 'A', _id : 1 },
{ name: 'B', _id : 2 },
{ name: 'C', _id : 3 },
{ name: 'D', _id : 4 },
{ name: 'E', _id : 5 }
];
$scope.array = [
{
"id": 910,
"language": {
"_id": "333",
"name": "Persian",
"abbreviation": "PE"
},
"business_unit": {
"_id": "2",
"name": "B"
}
},
{
"id": 909,
"language": {
"_id": "456",
"name": "English",
"abbreviation": "EN"
},
"business_unit": {
"_id": "3",
"name": "C"
}
},
{
"id": 908,
"language": {
"_id": "456",
"name": "Spanish",
"abbreviation": "SP"
},
"business_unit": {
"_id": "4",
"name": "D"
}
},
{
"id": 911,
"language": {
"_id": "343",
"name": "German",
"abbreviation": "GE"
},
"business_unit": {
"_id": "5",
"name": "E"
}
},
{
"id": 912,
"language": {
"_id": "696",
"name": "Russian",
"abbreviation": "RU"
},
"business_unit": {
"_id": "1",
"name": "A"
}
}]
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="MainCtrl">
<li ng-repeat="o in languages" ng-model="lang.language.name">
<input type="checkbox">
{{o.name}},
`</li>
<br><br><br>
<li ng-repeat="o in bu">
<input type="checkbox" ng-model="bu.business_unit.name">
{{o.name}},
`</li>
<br><br><br>
<div ng-repeat="arr in array filter : lang | filter : bu">
{{arr.language.name}} "and" {{arr.business_unit.name}}
</div>
<div>
You can use custom filter to achieve your goal:
custom fileter:
filter('myFilter', function() {
return function(items, search) {
var filterItems = {
search: search,
result: []
};
if (!search.needFilter) {
return items;
}
angular.forEach(items, function(value, key) {
if (this.search.language[value.language.name] === true || this.search.business_unit[value.business_unit.name] === true) {
this.result.push(value);
}
}, filterItems);
return filterItems.result;
};
})
HTML:
<p>Search by Language:</p>
<li ng-repeat="o in languages">
<input type="checkbox" ng-model="search.language[o.name]"> {{o.name}}
</li>
<p>Search by Unit:</p>
<li ng-repeat="o in bu">
<input type="checkbox" ng-model="search.business_unit[o.name]"> {{o.name}}
</li>
<p><b>Result:</b></p>
<div ng-repeat="arr in array | myFilter : search:false ">
{{arr.language.name}} "and" {{arr.business_unit.name}}
</div>
For more details see PLUNKER DEMO

AngularJS adding and pushing in nested JSON objects

I have a JSON Object like this :
{
"Name": "Shivansh",
"RollNo": "1",
"Stream": "CSE",
"OverallScore": "76",
"Semester": [
{
"SemesterName": "FY-2012 - 1",
"TotalScore": "78.00",
"StartDate" : "2012-02-14",
"EndDate" : "2012-07-16",
"Amount" : "55000",
"Subject": [
{
"subjectname": "maths",
"score": "81"
},
{
"subjectname": "chemistry",
"score": "79"
},
{
"subjectname": "physics",
"score": "77"
}
]
},
{
"SemesterName": "FY-2013-1",
"TotalScore": "76.00",
"StartDate" : "2013-02-16",
"EndDate" : "2014-07-16",
"Amount" : "55000",
"Subject": [
{
"subjectname": "ADA",
"score": "80"
},
{
"subjectname": "Operating System",
"score": "77"
},
{
"subjectname": "Databases",
"score": "73"
},
{
"subjectname": "Economics",
"score": "71"
}
]
}
]
}
Now i want to add another semester field into this JSON by using angularJS. Can anyone help me how to achieve this. The next field that I would add may look like:
{
"SemesterName": "FY-2013-2",
"TotalScore": "75.00",
"StartDate" : "2011-02-16",
"EndDate" : "2012-07-16",
"Amount" : "55067800",
"Subject": [
{
"subjectname": "Sets and Probability",
"score": "78"
},
{
"subjectname": "Networking and Security",
"score": "76"
},
{
"subjectname": "Advanced DataBases",
"score": "72"
},
{
"subjectname": "Economics-2",
"score": "70"
}
]
}
so far I am using this type of controllers as mentioned below:
$scope.addRowSubject = function() {
$scope.insertsub = {
//id = $scope.getSubject.length+1;
subjectname : '1',
score : '1'
};
$scope.getSubject.push($scope.insertsub);
};
getSubject is the list of subjects which are present in one semester field. I am able to get this list without any issues.
$scope.addRowSemester = function() {
$scope.insertsem = {
//id = $scope.getSemester.length+1;
StartDate : "1",
EndDate : "1",
Amount : "1",
SemesterName : "1",
TotalScore : "1",
Subject : ""
}
$scope.getSemester.push($scope.insertsem);
};
getSemester is the list of Semesters in a Student.
I am able to push a semester field inside my JSON but as the Subject field is null i am not able to push the subject field. I hope you are getting the idea.
So any suggestions about this..
Thanks in advance.
Subject properties of your jsonObject is should be an instance of array, like this:
$scope.addRowSemester = function() {
$scope.insertsem = {
//id = $scope.getSemester.length+1;
StartDate : "1",
EndDate : "1",
Amount : "1",
SemesterName : "1",
TotalScore : "1",
Subject : []
}

How to query a json file?

Here is the file I would like to parse
I receive a file from a webservice in JSON format.
I would like to parse the content in such a way that I display the name of the president from the USA
{
"response": {
"result": {
"Countries": {
"row": [
{
"no": "1",
"FL": [
{
"content": "USA",
"val": "Country"
},
{
"content": "Barack Obama",
"val": "President"
}
]
},
{
"no": "2",
"FL": [
{
"content": "Cuba",
"val": "Country"
},
{
"content": "Raul Castro",
"val": "President"
}
]
}
]
}
}
}
}
The expected output
{ presidents: [
{ "name": "Barack Obama"}
]
}
could you provide a solution using a kind of JSON XPath?
Assuming that you are loading the response into a variable data:
var data = {
"response" : {
"result" : {
"Countries" : {
"row" : [{
"no" : "1",
"FL" : [{
"content" : "USA",
"val" : "Country"
}, {
"content" : "Barack Obama",
"val" : "President"
}
]
}, {
"no" : "2",
"FL" : [{
"content" : "Cuba",
"val" : "Country"
}, {
"content" : "Raul Castro",
"val" : "President"
}
]
}
]
}
}
}
};
You can then filter your data like this:
data.response.result.Countries.row.filter(function (el) {
return (el.FL[0].content == "USA");
})[0].FL[1];
To get to:
{
"content" : "Barack Obama",
"val" : "President"
}
To get the name, simply specify "content"
data.response.result.Countries.row.filter(function(el){
return (el.FL[0].content == "USA");
})[0].FL[1].content;
EDIT 1
One could search a json object like a string.
If we know that the element will have no children, then we could use something like this:
function find(query,obj) {
var str = JSON.stringify(obj);
var start = str.substr(0,str.indexOf(query)).lastIndexOf('{');
var end = str.substr(start,str.length).indexOf('}');
return str.substr(start,end);
}
console.log(find('"content":"USA"',data))
Despite of the age of the question I want to add this answer as reference for future visitors with the same problem:
You can use JSONPath. The page contains a description and an implementation in JavaScript and PHP.
t = {
"response": {
"result": {
"Countries": {
"row": [
{
"no": "1",
"FL": [
{
"content": "USA",
"val": "Country"
},
{
"content": "Barack Obama",
"val": "President"
}
]
},
{
"no": "2",
"FL": [
{
"content": "Cuba",
"val": "Country"
},
{
"content": "Raul Castro",
"val": "President"
}
]
}
]
}
}
}
}
res={};//Here we will store result
for (i in t.response.result.Countries.row) {
// get current country
country = t.response.result.Countries.row[i].FL[0].content;
// get current president
president = t.response.result.Countries.row[i].FL[1].content;
if (country == 'USA') {
res.presidents=[{name:president}];
break;
}
}

Javascript - Finding in subarray by value from another array

I have two javascript objects:
var classroom = {
"number" : "1",
"student" : [
{
"number" : 1,
"items" : [
{
"key" : "00000000000000000000001C",
"date" : "2016-04-21T17:35:39.997Z"
}
]
},
{
"number" : 2,
"items" : [
{
"key" : "00000000000000000000001D",
"date" :"2016-04-21T17:35:39.812Z"
},
{
"key" : "00000000000000000000002N",
"date" :"2016-04-21T17:35:40.159Z"
},
{
"key" : "00000000000000000000002Ñ",
"date" :"2016-04-21T17:35:42.619Z"
}
]
}
],
}
AND
var items = [
{
"fields" : {
"tags" : [
{
"key" : "00000000000000000000001C",
"Batch" : "50",
"Bin" : "01",
"Tray" : "02"
},
{
"key" : "00000000000000000000002N",
"Batch" : "55",
"Bin" : "05",
"Tray" : "12"
},
{
"key" : "000000000000228510000032",
"Batch" : "12",
"Bin" : "12",
"Tray" : "01"
}
],
"Name" : "Rubber"
},
"_id" : "56d19b48faa37118109977c0"
},
{
"fields" : {
"tags" : [
{
"key" : "00000000000000000000001D",
"Batch" : "50",
"Bin" : "01",
"Tray" : "05"
},
{
"key" : "00000000000000000000002Ñ",
"Batch" : "52",
"Bin" : "07",
"Tray" : "02"
},
{
"key" : "221567010000000000000089",
"Batch" : "11",
"Bin" : "15",
"Tray" : "03"
}
],
"Name" : "Book"
},
"_id" : "56d19b48faa37118109977c1"
}
];
Ok, I need to create a function that goes through every item of every student in classroom variable. With each item, I need to find in the items array the object that has the exact same key in one of its tags.
My code is getting strange results...missmatching items...
var finalitems = [];
classroom.student.forEach( function (student){
student.items.forEach( function (obj){
items.forEach( function (theitem){
theitem.fields.tags.forEach( function (tag){
if (tag.key === obj.key) {
var newitem = theitem;
newitem.tag = obj;
finalitems.push(newitem);
}
});
});
});
});
I know that foreach is a kind of a pointer but I don't really understand why it is working strange and how it should be done.
Regards,
javascript variables only save object references, not the actual object in memory, so this line:
var newitem = theitem;
means newitem refers to the same object as theitem, NOT create a new object from theitem.
so
newitem.tag = obj;
is the same as
theitem.tag = obj;
Which means you're modifying the input objects, that's why you won't get the expected output.
To get the desired behavior you need to create a copy of theitem and assign that object to newitem variable:
var newitem = Object.create(theitem);
Maybe this helps with a lot more iterations.
var classroom = { "number": "1", "student": [{ "number": 1, "items": [{ "key": "00000000000000000000001C", "date": "2016-04-21T17:35:39.997Z" }] }, { "number": 2, "items": [{ "key": "00000000000000000000001D", "date": "2016-04-21T17:35:39.812Z" }, { "key": "00000000000000000000002N", "date": "2016-04-21T17:35:40.159Z" }, { "key": "00000000000000000000002Ñ", "date": "2016-04-21T17:35:42.619Z" }] }] },
items = [{ "fields": { "tags": [{ "key": "00000000000000000000001C", "Batch": "50", "Bin": "01", "Tray": "02" }, { "key": "00000000000000000000002N", "Batch": "55", "Bin": "05", "Tray": "12" }, { "key": "000000000000228510000032", "Batch": "12", "Bin": "12", "Tray": "01" }], "Name": "Rubber" }, "_id": "56d19b48faa37118109977c0" }, { "fields": { "tags": [{ "key": "00000000000000000000001D", "Batch": "50", "Bin": "01", "Tray": "05" }, { "key": "00000000000000000000002Ñ", "Batch": "52", "Bin": "07", "Tray": "02" }, { "key": "221567010000000000000089", "Batch": "11", "Bin": "15", "Tray": "03" }], "Name": "Book" }, "_id": "56d19b48faa37118109977c1" }],
finalitems = [];
classroom.student.forEach(function (student) {
student.items.forEach(function (studentItem) {
items.forEach(function (item) {
item.fields.tags.forEach(function (itemTag) {
if (itemTag.key === studentItem.key) {
finalitems.push({
key: studentItem.key,
date: studentItem.date,
Batch: itemTag.Batch,
Bin: itemTag.Bin,
Tray: itemTag.Tray,
});
}
});
});
});
});
document.write('<pre>' + JSON.stringify(finalitems, 0, 4) + '</pre>');

Categories