AngularJS Multidimensional JSON - javascript

I know this is a bit basic but i'm struggling to get my head round it, I have a web service that returns the follow JSON:
[{"search_id":"1","user_id":"1","all_words":"php","not_words":"C++","one_words":"java","created_at":null,"updated_at":null,"search_name":null},{"search_id":"2","user_id":"1","all_words":"second","not_words":"not","one_words":"one","created_at":null,"updated_at":null,"search_name":null}]
So when it gets to angular I end up with the following:
Array[2]
0: Object
$$hashKey: "object:5"
all_words: "php"
created_at: null
not_words: "C++"
one_words: "java"
search_id: "1"
search_name: null
updated_at: null
user_id: "1"
__proto__:
1: Object
$$hashKey: "object:6"
all_words: "second"
created_at: null
not_words: "not"
one_words: "one"
search_id: "2"
search_name: null
updated_at: null
user_id: "1"
__proto__:
Which is a real pain to work with in ng-repeat, how would I go about being able to access it like so(rough example)
ng-repeat="item in items"
{{ item.search_id }}
to be clear the only way I can get data from it is by doing:
<tr ng-repeat="items in data">
<td ng-repeat="(key, value) in items"> </td>
</tr>
Controller code is here:
testAPI.getSearches().then(function (data) {
$scope.data= testAPI.searchList();
console.log($scope.data);
}, function (error) {
alert("Error in getSearches");
});
getsearches as follows, searchList returns the searches variable:
getSearches: function() {
var deferred = $q.defer();
$http({
url: 'http://localhost/api/api/tray/search/list'
}).success(function (data) {
searches = data;
console.log(data);
deferred.resolve(data);
}).error(function (data) {
alert('Error');
deferred.reject(data);
});
return deferred.promise;
},
Hrm thanks for the responses guys but the plain "item in data" does not work in my case I have to use (key,value) in items inside a nested ng repeat, any ideas what i'm missing?
By the way not sure if this matters put the HTML is inside a partial and i'm using ui router for the navigation?
UPDATE
Thank you all very much for your help, looks like this problem was caused by a typo on a containing HTML element and the controller not being setup properly because I messed up the ui router setup. Once i've had a chance to make sure i've missed nothing else i'll post back.

This seems to be working fine. Just make sure you're data is tied to your $scope.
http://jsfiddle.net/f4zdfh72/
function MyCtrl($scope) {
$scope.data = [{
"search_id": "1",
"user_id": "1",
"all_words": "php",
"not_words": "C++",
"one_words": "java",
"created_at": null,
"updated_at": null,
"search_name": null
}, {
"search_id": "2",
"user_id": "1",
"all_words": "second",
"not_words": "not",
"one_words": "one",
"created_at": null,
"updated_at": null,
"search_name": null
}]
}
<div ng-controller="MyCtrl">
<div ng-repeat='item in data'>
THIS IS DATA: {{item.one_words}}
</div>
</div>
Note: run it in the JSFiddle. Stack snippet is just for code preview

works fine for me: http://plnkr.co/edit/ubiWcF3CemeKo6dzkvNC?p=preview
var app = angular.module("myApp", []);
app.controller('myCtrl', ['$scope', function($scope){
$scope.data = JSON.parse('[{"search_id":"1","user_id":"1","all_words":"php","not_words":"C++","one_words":"java","created_at":null,"updated_at":null,"search_name":null},{"search_id":"2","user_id":"1","all_words":"second","not_words":"not","one_words":"one","created_at":null,"updated_at":null,"search_name":null}]')
}]);

Maybe I am missunderstanding, but this should actually work. Plunker The Example includes the Controller As and $scope approaches.
Controller
angular
.module("app", [])
.controller("MainController", ['$scope', function($scope) {
var vm = this;
var json = '[{"search_id":"1","user_id":"1","all_words":"php","not_words":"C++","one_words":"java","created_at":null,"updated_at":null,"search_name":null},{"search_id":"2","user_id":"1","all_words":"second","not_words":"not","one_words":"one","created_at":null,"updated_at":null,"search_name":null}]';
vm.items = JSON.parse(json);
$scope.items = JSON.parse(json);
}]);
html
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-controller="MainController as vm">
<h1>Items Controller As</h1>
<div ng-repeat="item in vm.items">
{{ item.search_id }}
</div>
<h1>Items $scope</h1>
<div ng-repeat="item in items">
{{ item.search_id }}
</div>
<script data-require="angular.js#1.3.6" data-semver="1.3.6" src="https://code.angularjs.org/1.3.6/angular.js"></script>
<script src="script.js"></script>
</body>
</html>
Edit:
Added my comment from above.
Why do you use two nested ng-repeats? I guess one object of the array should be one row in the table. Therefore
<tr ng-repeat="item in data">
...
<td>{{item.search_name}}</td>
...
</tr>
should work. Unless you need the keys of the object, than you need (key, value).

Related

AngularJs read json file

I have a tree which is created dynamically with json.There is a one controller and in this controller there is a json array.I use this json to create a tree,but i need to read this json from file externally.
My controller;
..........
$scope.myjson =
{
"option1": [
{
"child":[{"label":"Test1" },{"label":"Test2"}],
"id": "option1"
}
],
"option2": [
{
"child":[{"label":"Test1.1",}],
"id": "option2"
}
],
...........
}
Json array reading part(In Controller);
angular.forEach($scope.myjson, function(value, key)
{
if (key === 'option1')
{
for(var t=0;t<$scope.myjson[key][0].child.length;t++)
{
......Somethings.........
}
}
I want to call json file and read it to create a tree.How can i call json file and read in angularjs?
Reading JSON in Angular is pretty straightforward with $http. Keep in mind that $http will return a promise, and you need to resolve it before processing.
Here is a sample code:
$http.get('assets/messages.json').then(function (data) {
/** work with data **/
});
Here you can get a complete tutorial regarding your problem. You just need to modify it in your way.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="customersCtrl">
<ul>
<li ng-repeat="x in names">
{{ x.Name + ', ' + x.Country }}
</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://www.w3schools.com/angular/customers.php")
.success(function(response) {$scope.names = response.records;});
});
</script>

trying to display json data with angularjs ng-repeat not working

I've seen so many ways to do this, but most are pretty old and I want to make sure I'm doing this correctly. Right now, the way I'm using isn't working and I feel like I'm missing something.
I'm getting the JSON back fine, I just need to get it to display in a table after I click the button.
Here is the JSON. This is how I'm going to get it from our server, I can't add any "var JSON =" or add any scope like "$scope.carrier" to the data, unless there's a way to add it after I've fetched the data.
{
"carrier":
[
{
"entity": "carrier",
"id": 1,
"parentEntity": "ORMS",
"value": "Medica"
}, {
"entity": "carrier",
"id": 2,
"parentEntity": "ORMS",
"value": "UHG"
}, {
"entity": "carrier",
"id": 3,
"parentEntity": "ORMS",
"value": "Optum"
}, {
"entity": "carrier",
"id": 4,
"parentEntity": "ORMS",
"value": "Insight"
}, {
"entity": "carrier",
"id": 5,
"parentEntity": "ORMS",
"value": "Insight"
}
]
}
Here is the app.js file to bring back the JSON data:
var app = angular.module('myTestApp', []);
app.controller('myController', ['$scope', '$http', function($scope, $http) {
var url = 'test.json';
$scope.clickButton = function() {
$http.get(url).success(function(data) {
console.log(data);
});
}
}]);
And then of course the HTML:
<div class="col-lg-12 text-center">
<button type=button class="btn btn-primary load" ng-click="clickButton()">Click!</button>
<table class="">
<tbody ng-repeat="carrier in carriers">
<tr>
<td>
<h3 class="">{{ module.entity }}</h3>
<h3 class="">{{ module.id }}</h3>
<h3 class="">{{ module.parentEntity }}</h3>
<h3 class="">{{ module.value }}</h3>
</td>
</tr>
</tbody>
</table>
</div>
I'm also wondering if I can use the ng-grid to put this in a table. I know they just upgraded it to ui grid so I'm not sure if this is still a feasible approach.
Also, I'm not getting errors, the data just won't display in the table right now. All I know is its returning the data properly, just not displaying in the table.
Any help is appreciated.
I looked at your plunker seems like you need to:
add angular script
wire the app and the controller
your variable in the repeater is wrong, I change it
take a look to this fixed plunker:
http://plnkr.co/edit/TAjnUCMOBxQTC6lNJL8j?p=preview
$scope.clickButton = function() {
$http.get(url).success(function(returnValue) {
alert(JSON.stringify(returnValue.carrier));
$scope.carriers = returnValue.carrier;
});
}
You never assign the value of the returned array to $scope.carriers.
At the line where you say console.log(data); add this:
$scope.carriers = data.data;
Here is the updated clickButton function (with a variable name change to reduce confusion):
$scope.clickButton = function() {
$http.get(url).success(function(returnValue) {
$scope.carriers = returnValue.data;
});
};

updating text on view from ng-repeat

I have problem with updating view by using ng-repeat.
When click on text, it doesnt update but it overwrites below. (I want have panel with names(links) and show its description on view)
I have searched everything and couldnt find answer or something useful what would help me.
html:
<body>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li><a ng-repeat="item in items" ng-click="getInfo(item)" > {{item.name}} <br> </a></li>
</ul>
</div>
<hr>
<div ng-controller="myInfo">
<div ng-repeat="info in item" >
<h3>Name: {{info.name}}</h3>
<p> ID: {{info._id}}</p>
<p> temp: {{info.temp}} </p>
</div>
</div>
</div>
</body>
js
var app = angular.module('myApp', [])
app.controller('myCtrl', function($scope, $http, shareDataService) {
$http.jsonp('data.json').success(function(data) {
$scope.items = data;
});
$scope.getInfo = function(item) {
shareDataService.addItem(item);
}
});
app.controller('myInfo', function( $scope, shareDataService ){
$scope.item = shareDataService.getItem();
});
app.service('shareDataService', function() {
var myItem = [];
var addItem = function(newObj) {
myItem.push(newObj);
}
var getItem = function(){
return myItem;
}
return {
addItem: addItem,
getItem: getItem
};
});
json
angular.callbacks._0([
{
"_id": 1,
"temp": "asdgdf",
"name": "name1"
},
{
"_id": 2,
"temp": "asdasdasd",
"name": "name2"
},
{
"_id": 3,
"temp": "asasdasdadgdf",
"name": "name3"
}
]);
Plunker: http://plnkr.co/edit/X65oH0yAkRnN8npKnFY2?p=preview
You have an error in your console. Just add track by to your ng-repeat:
<div ng-repeat="info in item track by $index">
ng-repeat needs a unique id to track the items in order to be able to update them. If you add the same item twice, ng-repeat sees the same item twice, ans loses its mind. Using $index (which is unique) resolves that issue.
Keep in mind that using $index is adequate here, but it's preferred to use a unique id from the object if you can.
EDIT:
If your issue is that you want to see only the one element you clicked on in your view, then the issue is that you are adding your item to an array, when you should just be setting a value in your service. And, obviously, no need of a ng-repeat in your view.
http://plnkr.co/edit/Wfg9KhCWKMDreTFtirhR?p=preview
JS:
app.controller('myCtrl', function($scope, $http, shareDataService) {
//[...]
$scope.getInfo = function(item) {
shareDataService.setItem(item);
}
});
app.controller('myInfo', function( $scope, shareDataService ){
$scope.$watch(function () {
return shareDataService.getItem();
}, function (value) {
$scope.info = value;
})
});
app.service('shareDataService', function() {
var myItem;
return {
setItem: function(newObj) {
myItem = newObj;
},
getItem: function(){
return myItem;
}
};
});
HTML:
<div ng-controller="myInfo" ng-show="info">
<h3>Name: {{info.name}}</h3>
<p> ID: {{info._id}}</p>
<p> temp: {{info.temp}} </p>
</div>
If you only want to display information of the item that you just have clicked, then we don't need the second ng-repeat (as jlowcs said).
We also don't have to defined myItem as a array, it's just unnecessary, I think.
Edit:
how embarrassing i am, my answer look exactly to same as jlowcs's. I guess I took to much time to figure out the answer.
One thing to add up:
Why do I need a $watch in myInfo controller?
Because at the first time, we use ng-repeat, this component do the watch part for us. Then when I remove ng-repeat, I need to watch for data changing by myself.

Angular JS, put json to ng-repeat out of an event fails

I am new to Angular and I have this issue that I don't get solved. I have read today alot about good style and $scope soup but I could not find an answer to this.
It is the following, very easy example:
I have a controller with an ng-repeat inside and an input with a change-event.
<div id="searchbar" data-ng-controller="SearchCtrl">
<input id="search" autocomplete="off" data-ng-model="search" data-ng-keyup="getResults( search );" />
<div id="input_results">
<li data-ng-repeat="x in names">
{{ x.Country }}
</li>
</div>
</div>
When I assign some json directly from the controller function everything works fine.
var app = angular.module("myApp", []);
var SearchCtrl = function($scope, $http, HTTPService) {
console.log("Control opened");
$scope.names = [{
"Country": "TEXT"
}];
};
When I try to assign json out of the event, then I receive there "parent is null"
var app = angular.module("myApp", []);
var SearchCtrl = function($scope, $http, HTTPService) {
var _this = this;
console.log("Control opened");
$scope.getResults = function(searchstring) {
console.log("Execute search: " + searchstring);
$scope.names = [{
"Country": "TEXT"
}];
_this.getResults(searchstring, $scope, $http);
};
};
I don't know how I can pass the correct scope to getResults() or how to solve this issue. Additionally I have read that it is best to use dots in model names like SearchStrl.search to avoid shadowing.
I am also confused about the behaviour, when I change $scope.search it works fine inside the getResult() function, but why not with the ng-repeat.
It would be nice if somebody could explain me the reason for this behaviour.
Thank you.
Your ng-repeat code fails to work because he doesn't has an array to repeat on through.the code only creates the array after you activated 'getResults' function.
in your controller you shold have something like this:
app.controller('CTRL1', function($scope){
$scope.names = [{
"Country": "TEXT"
}]; //your array
$scope.getResults = function(search) {
//your search code.
}
})
I can see you're trying to make a list of items with a search. instead of the above code I will suggest you do as followed:
<div data-ng-controller="SearchCtrl">
<input data-ng-model="search" /> <!-- creates a search instance- -->
<div id="input_results">
<!--filter by search model -->
<li data-ng-repeat="x in names | filter: search">
{{ x.Country }}
</li>
</div>
and in your code:
$scope.names = [{
"Country": "TEXT"
}];

Nested JSON not display in ng-repeat

I'm having trouble accessing the nested JSON using the ng-repeat directives. I know it is working because the not nested part of the JSON object is displaying.
Here is a plunker of my code: http://plnkr.co/edit/V2iURMa8t7vG9AqDFMOf?p=preview
JavaScript:
var app = angular.module("app", [ ]);
app.controller("AppTest", function($scope){
$scope.currentInfo=[{"id":0,"article":"JavaScript Conquers the World","publisher":"Daily Times","meta_data":{"comments":4}},
{"id":1,"article":"The Problem with Foobar","publisher":"New York Times","meta_data":{"comments":27}}];
$scope.tableInfo=[{"name":"id","dataType":"Integer","isEditable":false},
{"name":"article","dataType":"String","isEditable":true},
{"name":"publisher","dataType":"String","isEditable":false},
{"name":"meta_data.comments","dataType":"Integer","isEditable":false}];
});
HTML:
<body ng-app="app" ng-controller="AppTest as app"
<table>
<tbody ng-repeat="anotherItem in currentInfo">
<tr>
<td ng-repeat="item in tableInfo">{{anotherItem[item.name]}}</td>
</tr>
</tbody>
</table>
</body>
Another solution that is better is to add function in the controller that will resolve the value for you. The issue with your solution is that you need Angular to resolve meta_data.comments, but it is treating it as the string that is used in the array lookup since it has already resolved item.name.
$scope.resolveLookup = function(object, lookup) {
var depth = lookup.split('.').length;
var currentObj = object;
for(var x=0; x<depth; x++) {
currentObj = currentObj[lookup.split('.')[x]];
}
return currentObj;
};
Then change the HTML to look like:
<td ng-repeat="item in tableInfo">{{resolveLookup(anotherItem,item.name)}}</td>
Here is the Plunker: http://plnkr.co/edit/RVd2ncwstyQtCtdhcC9U?p=preview
The issue is that it is putting 'metadata.comments' in the [] and it doesn't realize that it needs to be resolved again by angular. I can't think of fix without changing the data structure of your 'tableInfo' object.
Here is how I would do it.
Change table info to:
$scope.tableInfo = [{
"name": ["id"],
"dataType": "Integer",
"isEditable": false
}, {
"name": ["article"],
"dataType": "String",
"isEditable": true
}, {
"name": ["publisher"],
"dataType": "String",
"isEditable": false
}, {
"name": ["meta_data", "comments"],
"dataType": "Integer",
"isEditable": false
}];
Change your HTML to:
<td ng-repeat="item in tableInfo" ng-if="item.name.length==1">{{anotherItem[item.name[0]]}}</td>
<td ng-repeat="item in tableInfo" ng-if="item.name.length==2">{{anotherItem[item.name[0]][item.name[1]]}}</td>
Here is the Plunker: http://plnkr.co/edit/q9lHZ2TD7WZ74b2f6Ais?p=preview

Categories