I am unsure if this has got anything to do with AngularJS at all and if it is only JSON related.
Anyhow, let us say that we have the following JSON:
$scope.dataSets = {
"names": ["Horace", "Slughorn", "Severus", "Snape"],
"genders": ["Male", "Female"]
}
Now, I am using the ng-repeat directive to print the above as follows:
<div ng-repeat="data in dataSets>
//Continue readig to know what I am expcting here
</div>
What I expect within the <div></div> tags is to print "name" and "genders". That is, I wish to print the keys of the JSON. I have no idea what the keys are, as in they could be anything. How can I do this?
As docs state it:
(key, value) in expression – where key and value can be any user defined identifiers, and expression is the scope expression giving the collection to enumerate.
<div ng-repeat="(key, data) in dataSets">
{{key}}
</div>
for accessing Json key-value pair from inside controller in AngularJs.
for(var keyName in $scope.dataSets){
var key=keyName ;
var value= $scope.dataSets[keyName ];
alert(key)
alert(JSON.stringify(value));
}
if dataSets is an array and not an object you first need to ng-repeat the array items and then the key or value.
<div ng-repeat="item in dataSets">
<div ng-repeat="(key, value) in item">
{{key}}
{{value}}
</div>
</div>
just my 2 cents.
For every dataSet in dataSets, print the key and then iterate through the individual items:
<div ng-repeat="(key, dataSet) in dataSets">
<div>{{key}}</div>
<div ng-repeat="value in dataSet">
{{value}}
</div>
</div>
{{dataset}} can be displayed in one go also, the array would be displayed as a comma separated list of values.
Related
JSON
{
"cars":
{
"12345": [1960, 1961, 1962],
"4567": [2001, 2002]
}
}
HTML
<strong>Plate and year</strong>
<div *ngFor="let list of lists">
{{list.cars}}
</div>
I need to display like this:
Plate and year
12345- 1960, 1961, 1962.
4567- 2001, 2002.
Based on your data structure, you can achieve this using the KeyValuePipe and additional nested *ngFor. KeyValuePipe allows you to iterate over an object similar to Object.entries providing a key and value property for each item. In this case the value will be an array that you can iterate over using an *ngFor:
<strong>Plate and year</strong>
<div *ngFor="let list of lists">
<div *ngFor="let car of list.cars | keyvalue">
<div>{{car.key}} - <div *ngFor="let year of car.value">{{year}}</div>
</div>
</div>
</div>
Here is an example in action.
Hopefully that helps!
I need to get values from json (comes from merged MySQL tables).
I've tried a several solutions from previous topic but none of them worked for me.
access key and value of object using *ngFor
my JSON format is:
[
{
"idemployee":1,
"name":"Ernest",
"surename":"Pająk",
"role":"Obsługa Baru",
"employeehours":[
{
"idemployeehours":1,
"date":"2019-01-10T23:00:00.000+0000",
"quantity":8.0
}
]
}
]
and what I got is "Key: 0 and Value: " (answer from Pardeep Jain topic above)
EDIT:
this is my code:
<div *ngFor="let item of employee| keyvalue">
Key: <b>{{item.key}}</b> and Value: <b>{{item.value}}</b>
employee comes from Angular component and gives mentioned JSON. The problem is getting nested values from "employeehours" (like quantity)
You don't need the keyvalue pipe. employeehours is an array, so you just need a nested *ngFor for the array, so example where you have stored your data in an employees array:
<div *ngFor="let emp of employees">
<p>Name: {{emp.name}} {{emp.surename}}</p>
<div *ngFor="let hour of emp.employeehours">
<p>Date: {{hour.date | date: 'shortDate'}}</p>
<p>Quantity: {{hour.quantity}}</p>
</div>
</div>
DEMO
if you run keyValue pipe on array object you got the keys as the index of the values in the array so tha why you need a nested ngFor to run keyvalue pipe on the value of the array
<div *ngFor="let item of employee">
<div *ngFor="let emp of item |keyvalue ">
Key: <b>{{emp.key}}</b> and Value: <b>{{emp.value}}</b>
</div>
</div>
demo 🔥🔥
UPDATED!
if you want to support sohow keys value of employeehours where the value is array best cases here to create a component to do all of this and use this component to render the new values like recursion
component
export class RenderComponent {
#Input() items = [];
isArray(value) {
return value instanceof Array
}
}
template
<div *ngFor="let item of items">
<div *ngFor="let obj of item | keyvalue " class="well">
Key: <b>{{obj.key}}</b> and Value: <b>{{obj.value}}</b>
<ng-container *ngIf="isArray(obj.value)">
<render [items]="obj.value"></render>
</ng-container>
</div>
</div>
demo 💣💣
I have json data in controller as response. I have to print that data in html.
for that I have done as below:
In my controller
.controller('DataImportControl', ['$scope','$http', '$location', '$rootScope' , function($scope, $http, $location, $rootScope) {
console.log(" In dataimportCtrl");
$scope.readCustomer = function(){
console.log("in read customer");
$http.post('/custimport').success(function(response) {
console.log("in controller");
console.log("controller:"+response);
$scope.data=response;
}).error(function(response) {
console.error("error in posting");
});
};
}])
My html code:
<html>
<head>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<div ng-app="" ng-controller="DataImportControl">
<form ng-submit="readCustomer()">
<button type="submit" >Submit</button>
</form>
<table class="table">
<thead>
<tr>
<th>Code exists in customer master</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="cust in data ">
<td>{{cust.customer_code}}</td>
</tr>
</tbody>
</table>
</div>
<div >
</div>
</body>
</html>
My json data as response in controller :
{"jarray":[{"customer_name":["Ankita"],"customer_code":["c501"]}]}
My question is how to print json data in html using ng-repeat in my case?
Thanks in advance...
I'm assuming you want to print out the actual object, in that case just do
{{cust | json}}
Wrap it in pre tags to have it prettified.
The data being returned from your service is strangely formatted. I would assume you have multiple records being returned, but you are only showing one in this example.
The record you are showing here is an object, with an array as one of the properties. It is not clear if your object has multiple arrays, or if this array has multiple customer objects embedded in it. However, I worked up a quick plunker showing how to iterate through in both situations.
first, if you intend to iterate through data directly, and data will hold multiple arrays, you would use the (key, value) syntax, since data itself is an object and not an array.
<div ng-repeat="(key, value) in data">
key: {{key}}
<br/>value: {{value}}
<div ng-repeat="customer in value">
Customer name: {{customer.customer_name}}
<br/>Customer code: {{customer.customer_code}}
</div>
</div>
However, if your data is only returning a single object property, jarray, and you will always be iterating through this same property, the outer ng-repeat is unnecessary:
<div ng-repeat="customer in data.jarray">
Customer name: {{customer.customer_name}}
<br/>Customer code: {{customer.customer_code}}
</div>
you may want to clean up your service, either in angular or on your server, and remove jarray all together, if it doesn't hold a specific significance to the data.
http://plnkr.co/edit/Nq5Bo18Pdj4yLQ13hnrJ?p=preview
i've got a string saved in my db
{"first_name":"Alex","last_name":"Hoffman"}
I'm loading it as part of object into scope and then go through it with ng-repeat. The other values in scope are just strings
{"id":"38","fullname":"{\"first_name\":\"Alex\",\"last_name\":\"Hoffman\"}","email":"alex#mail","photo":"img.png"}
But I want to use ng-repeat inside ng-repeat to get first and last name separate
<div ng-repeat="customer in customers">
<div class="user-info" ng-repeat="name in customer.fullname">
{{ name.first_name }} {{ name.last_name }}
</div>
</div>
And I get nothing. I think, the problem ist, that full name value is a string. Is it possible to convert it to object?
First off... I have no idea why that portion would be stored as a string... but I'm here to save you.
When you first get the data (I'm assuming via $http.get request)... before you store it to $scope.customers... let's do this:
$http.get("Whereever/You/Get/Data.php").success(function(response){
//This is where you will run your for loop
for (var i = 0, len = response.length; i < len; i++){
response[i].fullname = JSON.parse(response[i].fullname)
//This will convert the strings into objects before Ng-Repeat Runs
//Now we will set customers = to response
$scope.customers = response
}
})
Now NG-Repeat was designed to loop through arrays and not objects so your nested NG-Repeat is not necessary... your html should look like this:
<div ng-repeat="customer in customers">
<div class="user-info">
{{ customer.fullname.first_name }} {{ customer.fullname.last_name }}
</div>
This should fix your issue :)
You'd have to convert the string value to an object (why it's a string, no idea)
.fullname = JSON.parse(data.fullname); //replace data.fullname with actual object
Then use the object ngRepeat syntax ((k, v) in obj):
<div class="user-info" ng-repeat="(nameType, name) in customer.fullname">
{{nameType}} : {{name}}
</div>
My advise is to use a filter like:
<div class="user-info"... ng-bind="customer | customerName">...
The filter would look like:
angular.module('myModule').filter('customerName', [function () {
'use strict';
return function (customer) {
// JSON.parse, compute name, foreach strings and return the final string
};
}
]);
I had same problem, but i solve this stuff through custom filter...
JSON :
.........
"FARE_CLASS": "[{\"TYPE\":\"Economy\",\"CL\":\"S \"},{\"TYPE\":\"Economy\",\"CL\":\"X \"}]",
.........
UI:
<div class="col-sm-4" ng-repeat="cls in f.FARE_CLASS | s2o">
<label>
<input type="radio" ng-click="selectedClass(cls.CL)" name="group-class" value={{cls.CL}}/><div>{{cls.CL}}</div>
</label>
</div>
CUSTOM FILTER::
app.filter("s2o",function () {
return function (cls) {
var j = JSON.parse(cls);
//console.log(j);
return j;
}
});
Hi I am new to angular I have a requirment as follows.
app.js
$scope.fields = {
"fields": {
"LastName1": "ABC",
"FirstName1": "XYZ",
"LastName2": "123",
"FirstName2": "345",
"LastName3": "PQR",
"FirstName3": "ASD",
}
};
In my html I need to loop over this and display in
index.html
<tr ng-repeat="key in fields">
this doesn't seem to work. Please help.
I want my output as
LastName1 ABC
FirstName1 XYZ
and so on.
Also If user makes any changes to this, I want to be able to push the changes back to fields Json. Please help.
You can use the (key, value) in object syntax.
In your case :
<div ng-repeat="(key1, value1) in fields">
<li ng-repeat="(key2, value2) in value1">{{key2}} : {{value2}}</li>
</div>.
But :
You need to be aware that the JavaScript specification does not define
the order of keys returned for an object. (To mitigate this in Angular
1.3 the ngRepeat directive used to sort the keys alphabetically.)
Version 1.4 removed the alphabetic sorting. We now rely on the order
returned by the browser when running for key in myObj. It seems that
browsers generally follow the strategy of providing keys in the order
in which they were defined, although there are exceptions when keys
are deleted and reinstated. See
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_issues
If this is not desired, the recommended workaround is to convert your
object into an array that is sorted into the order that you prefer
before providing it to ngRepeat. You could do this with a filter such
as toArrayFilter or implement a $watch on the object yourself.
More details : https://docs.angularjs.org/api/ng/directive/ngRepeat
Edit : What if you want to change the object now ?
You can't do :
<div ng-repeat="(key1, value1) in fields">
<h3>{{key1}}</h2>
<li ng-repeat="(key2, value2) in value1">
<input ng-model="value2" /><br />
{{key2}} : {{value2}}
</li>
</div>
Why ? Because ng-model will change value2 in the current scope, and not in your object fields as you don't use dot notation.
For each item/iteration, ng-repeat creates a new scope, which
prototypically inherits from the parent scope, but it also assigns the
item's value to a new property on the new child scope.
More details : https://github.com/angular/angular.js/wiki/Understanding-Scopes
But you can do :
<div ng-repeat="(key1, value1) in fields">
<h3>{{key1}}</h2>
<li ng-repeat="(key2, value2) in value1">
<input ng-model="fields[key1][key2]" /><br />
{{key2}} : {{value2}}
</li>
</div>
Take a look !!!
Try change to:
<tr ng-repeat="(key, value) in fields.fields">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
Here is a working plunker where you can update the model: http://jsfiddle.net/ttgfybk0/1/
Repeat data is in object format like
{
"LastName1": "ABC",
"FirstName1": "XYZ",
"LastName2": "123",
"FirstName2": "345",
"LastName3": "PQR",
"FirstName3": "ASD",
}
use the ng-repeat="(key, value) in expression"
<tr ng-repeat="(key, value) in fields.fields">
<td>{{key}} {{value}}</td>
</tr>
working example ishttp://plnkr.co/edit/Y5lPH1?p=preview