I'm trying to access an object in JSON with AngularJS, and display the values. I have done this when I create an array in JSON but this time I want to show an example with an object. This is my code:
My JSON File
{ "user": {
"Name":"Ben",
"City":"New York"}}
My angular app
var app = angular.module('myApp', []);
app.controller('jsonObjectExample', function($scope, $http) {
$http.get("jsonobject.json").then(function (response) {
$scope.myData = response.data.user;
});
});
My HTML
<body>
<div ng-app="myApp" ng-controller="jsonObjectExample">
<ul>
<li ng-repeat="x in myData">
{{ x.Name + ', ' + x.City }}
</li>
</ul>
</div>
</body>
Here is a link to these files on plunker: https://plnkr.co/edit/uBRf99AjYH9zX0WuHsW3?p=preview
Can someone explain where I'm going wrong? Thanks.
remove the ng-repeat. myData is object, not an array so no need to use the ng-repeat
<body>
<div ng-app="myApp" ng-controller="jsonObjectExample">
<ul>
<li >
{{ myData.Name + ', ' + myData.City }}
</li>
</ul>
</div>
</body>
Demo
If you are using ng-repeat make sure the json which you are parsing should give some array value.
you can correct your json like:
{ "user": [{
"Name":"Ben",
"City":"New York"}]}
Other codes are working fine. Please check this
Related
I'm getting info from an API, and one of the returned values is a list of coupons. Per example:
[{"Consecutive":11,"Code":"E5ZQHZ","Cvv":"GNH","IdCoupon":77236},{"Consecutive":12,"Code":"WM96FY","Cvv":"NGE","IdCoupon":77237}]
What I need to do is concatenate the values from Consecutive, Code, Cvv and show them like a list (something like this):
<ul>
<li>'Code'/'cvv'/'consecutive'</li>
<li>'Code'/'cvv'/'consecutive'</li>
</ul>
How can I do that? I'm using Javascript and AngularJs.
You can use an ng-repeat in your ul like so:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$scope.data = [{
"Consecutive": 11,
"Code": "E5ZQHZ",
"Cvv": "GNH",
"IdCoupon": 77236
}, {
"Consecutive": 12,
"Code": "WM96FY",
"Cvv": "NGE",
"IdCoupon": 77237
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<ul ng-repeat="d in data">
<li>{{d.Code}} / {{d.Cvv}} / {{d.Consecutive}}</li>
</ul>
</div>
There are other possible solutions but this should set you up nicely.
I made the below code to learn Angular. It uses the input entered by user to make an ajax request for a json file that contains a list of object, then print that list to the user.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script type="text/javascript">
angular.module('myApp', [])
.controller('myController', function($http) {
var ctlr = this;
ctlr.param = "";
ctlr.responses = [];
this.makeQuery = function() {
$http.get('http://localhost:8080?p=' + ctlr.param))
.then(function(data) {
ctlr.response = data; // data -> [{key1: value1,...},...]
});
};
});
</script>
</head>
<body ng-app="myApp">
<div ng-controller="myController as mc">
<input type="text" ng-model="mc.param">
<input type="submit" ng-click="mc.makeQuery()" value="Submit">
<ul>
<li ng-repeat="res in responses">
<span>{{res.key1}}, {{res.key2}}</span>
</li>
</ul>
</div>
</body>
</html>
When I run this code in Chrome, I see a list of empty bullet points. Chrome DevTools shows the json file returned as expected so I know ctlr.param works. However the list has empty bullet points so ng-repeat does not work correctly. It seems I cannot access cltr.responses properly. Does anyone know why?
Your responses object is binded to this and not to $scope as you are using controller as
You should use mc.responses instead of responses
<li ng-repeat="res in mc.responses">
<span>{{res.key1}}, {{res.key2}}</span>
</li>
You can read more from johnpapa style
Above solution is right but as i checked the complete code and found that there is one mistake.
In script code
ctlr.response = data; // data -> [{key1: value1,...},...] should be
ctlr.responses = data; // data -> [{key1: value1,...},...]
I'm trying out Angular custom filter example from: https://scotch.io/tutorials/building-custom-angularjs-filters#filters-that-actually-filter which in my version looks like:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="demo" >
<div>
<p><strong>Original:</strong></p>
<ul class="list">
<li ng-repeat="x in example1">{{ x.name }}</li>
</ul>
<p><strong>Static Language Filter:</strong></p>
<ul class="list">
<li ng-repeat="x in example1 | staticLanguage">{{x.name }}</li>
</ul>
</div>
</div>
<script>
var app = angular.module('myApp', []);
var counter=0;
app.controller('demo', function($scope){
$scope.example1 = [
{name: 'C#', type : 'static'},
{name: 'PHP', type : 'dynamic'},
{name: 'Go', type : 'static'},
{name: 'JavaScript', type: 'dynamic'},
{name: 'Rust', type: 'static'}
];
});
// Setup the filter
app.filter('staticLanguage', function() { // Create the return function and set the required parameter name to **input**
return function(input) {
counter+=1;
console.log(counter);
var out = [];
// Using the angular.forEach method, go through the array of data and perform the operation of figuring out if the language is statically or dynamically typed.
angular.forEach(input, function(input) {
if (input.type === 'static') {
out.push(input);
}
});
return out;
};
});
</script>
</body>
</html>
It seems from console.log that for some reason custom filter function staticLanguage is called two times but from the code itself it is called only one time: ng-repeat="x in example1 | staticLanguage"
Anyone has any idea why?
P.S I've yet to figure out what does "dirty-checking" has to do with my question...
if I remove counter variable and just put some console.log("text") in it's place staticLanguage function is still called two times
As far as I am aware this is due to AngularJS dirty-checking and has been asnwered elsewhere here. This is normal, have a read of the link.
This is normal, angularjs uses a 'dirty-check' approach, so it needs to call all the filters to see if any changes exist. After this it detects that you have a change on one variable (the one that you typed) and then it re-executes all filters again to detect if it has other changes.
See the first answer of this question
How does data binding work in AngularJS?
Well, I don't know if this will serve to you , but here's a snippet working that could be a possible solution for you:
var app = angular.module('app', []);
app.controller('mainCtrl', function($scope) {
$scope.languages = [
{
"name":"C#",
"type":"static"
},
{
"name":"PHP",
"type":"dynamic"
},
{
"name":"Go",
"type":"static"
},
{
"name":"JavaScript",
"type":"dynamic"
},
{
"name":"Rust",
"type":"static"
}
];
$scope.static_languages = $scope.languages.filter(x => x.type == 'static');
$scope.dynamic_languages = $scope.languages.filter(x => x.type == 'dynamic');
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js">
</script>
</head>
<body ng-controller="mainCtrl">
<div>
<p><strong>All languages:</strong></p>
<ul class="list">
<li ng-bind="language.name" ng-repeat="language in languages"></li>
</ul>
<p><strong>Static Languages Filter:</strong></p>
<ul class="list">
<li ng-bind="language.name" ng-repeat="language in static_languages"></li>
</ul>
<p><strong>Dynamic Languages Filter:</strong></p>
<ul class="list">
<li ng-bind="language.name" ng-repeat="language in dynamic_languages"></li>
</ul>
</div>
</body>
</html>
I've got a function in my controller very easy that just stamp a console.log. I need to conditioning a button using a function but inside the ng-repeat the controller repeats everything many times! Is it normal? Is it possible avoid this? Thanks. An example here http://plnkr.co/edit/sME67gQEZQSLI9FOwEAG?p=preview
relative code:
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.4.5" data-semver="1.4.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="DigestApp">
<div ng-controller="UserCtrl as uc">
<h1>Please open the console to see</h1>
<ul>
<li ng-repeat="user in uc.users" ng-class="uc.userClasses(user)">
{{user.name}}
<button ng-if="uc.isUserEnabled(user)"
ng-click="uc.disableUser(user)">Disable</button>
</li>
</ul>
</div>
</body>
</html>
javascript:
angular.module("DigestApp", [])
.controller('UserCtrl', function(User) {
var vm = this;
vm.users = User.list();
vm.isUserEnabled = function(user) {
console.log('isUserEnabled');
return user.active;
};
vm.userClasses = function(user) {
console.log('userClasses');
return []
.concat(user.active ? ['user-active'] : [])
.concat(user.loggedIn ? ['user-logged-in'] : [])
.concat(user.isMe ? ['user-is-me'] : [])
.join(' ');
};
vm.disableUser = function(user) {
user.active = false;
};
})
.factory('User', function() {
return {
list: function() {
return [{
name: "me",
active: true,
loggedIn: true,
isMe: true
}];
}
};
});
Yes, this is normal. There is no way that angular can tell whether the result of the function will have changed, so it calls it on every digest loop. If you want to avoid that you should calculate the value once and set the result as an attribute on the user object.
<li ng-repeat="user in uc.users" ng-class="user.classes">
{{user.name}}
<button ng-if="user.active"
ng-click="uc.disableUser(user)">Disable</button>
</li>
and in the controller add some code to precalculate a user.classes attribute on each user object (and to update it when you change the state of the model).
Please update your li in the HTML to the below. I got it working here http://plnkr.co/edit/Cx5OZaY0dhmBT4WLYZpX?p=info.
<li ng-repeat="user in uc.users" ng-class="{ 'user-active': user.active, 'user-logged-in': user.loggedin, 'user-is-me': user.isme }">
{{user.name}}
<button ng-if="user.active" ng-click="uc.disableUser(user)">Disable</button>
</li>
By using a function in your ng-class and ng-if it was evaluating to often. You can just pass the scope variables instead.
I am struggling to display HTML code from JSON string. You can see HTML tags in address. Is there any way I can properly display it?
My template is:
<div ng-app ng-controller="jsonp_example">
<ul ng-repeat="item in data">
<li>{{item.ID}}</li>
<li>{{item.post_title}}</li>
<li ng-bind-html-unsafe="getContent(obj)">{{item.custom_fields.sponsor_address}}</li>
<li>
<img src="{{item.custom_fields.sponsor_logo}}" width="100">
<ul>
<li>
<hr>
</li>
</ul>
</li>
</ul>
</div>
And script:
function jsonp_example($scope, $http) {
$scope.getContent = function (obj) {
return obj.custom_fields.sponsor_address
};
var url = "https://eventident.com/api/getposts/?auth_key=s2mEus39R296M5F6n343A3dh9c62f7cm&custom_post=sponsors&callback=JSON_CALLBACK";
$http.jsonp(url).success(function (data) {
$scope.data = data.result;
});
}
Please feel free to amend my jsfiddle: http://jsfiddle.net/1295z4bc/
Did you include angular-sanitize.js as a dependency ? (as a script and as angular module dependency)
Also, you don't need to {{}} with ng-bind-html, just
<li ng-bind-html="item.custom_fields.sponsor_address"></li>
will do.
You need to include the ngSanitize service and directly use ng-bind-html.
Here is an updated jsfiddle from yours: http://jsfiddle.net/e01xj547/9/
You might need to explicitly trust the html string by using the $sce service. E.g var trustedHtml=$sce.trustAsHtml('<em>My html string</em>');
In your case to following usage would be appropirate:
function jsonp_example($scope, $http, $sce) {
$scope.getContent = function (obj) {
return $sce.trustAsHtml(obj.custom_fields.sponsor_address);
};
var url = "https://eventident.com/api/getposts/?auth_key=s2mEus39R296M5F6n343A3dh9c62f7cm&custom_post=sponsors&callback=JSON_CALLBACK";
$http.jsonp(url).success(function (data) {
$scope.data = data.result;
});
}
Example usage: http://jsbin.com/zopenoqipi/2/edit?html,js,output