How to make output data dynamic structure using AngularJS? - javascript

I'm new in angularJS and making a simple app, but I am finding it difficult to create output with dynamic data.
Here my html -
<div ng-app="MyApp">
<div ng-controller="TabsDemoCtrl">
<div ng-controller="TabsDemoCtrl">
<h1> How to make output dynamic data like this?</h1>
<table ng-repeat="customize in data">
<tr>
<th colspan="2">{{customize.product.name}}</th>
</tr>
<tr>
<td colspan="2">Assets</td>
</tr>
<tr>
<td>{{ How to bind ouput dynamic attribute data ? }}</td>
<td>{{ How to bind ouput dynamic subattribute ? }}</td>
</tr>
</table>
</div>
</div>
</div>
and here my JS -
angular.module('MyApp', [
'ui.bootstrap']);
(function(MyApp) {
'use strict';
MyApp.controller('TabsDemoCtrl', ['$scope', function($scope) {
// categories
$scope.data = [
{
product : {
name : 'Product 1'
},
assets : {
color : {
black : '/file/6d2ceb60-257b-47e6-9db0-3a2299ff75f2.png'
}
}
},
{
product : {
name : 'Product 2'
},
assets : {
soles : {
black : '/file/840ec1ff-6d27-40af-b4ca-277aa09ad147.png',
red : '/file/1970f2e2-b7a0-439c-98d9-b9ea1604c227.png'
},
material : {
black : '/file/aebe8f68-60fd-4fda-bd46-00e80f190ba2.png',
green : '/file/e225e20d-5b97-4a60-8337-0551064a8d8c.png'
},
lining : {
blue : '/file/6d2ceb60-257b-47e6-9db0-3a2299ff75f2.png',
red : '/file/280fecb5-ebe5-47cb-85f4-4d1bf6dd8ed0.png'
}
}
}
];
}]);
})(angular.module('MyApp'));
I tried to make an output of dynamic structure data in this link demo but it doesn't show.
So how to make view with this dynamic data ?

quick hint:
you can use something like
<li ng-repeat="(key,val) in product.assets"></li>
to render all keys and values. now you have to check whether the val is an object or a string. if its an object you have to render another level of KV pairs...
<div>
<ul>
<li ng-repeat="product in data">
<p>{{product.product.name}}</p>
<ul>
<li ng-repeat="(key,val) in product.assets">
{{key}}
<ul>
<li ng-repeat="(key,val) in val">
{{key}} => {{val}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
I'll let you do the template to display recursive data and the data validation. do not use (key,val) template recursion on strings!!
refer to this: http://jsfiddle.net/brendanowen/uXbn6/8/

Check this link http://plnkr.co/edit/gFSXHT0YUzD0lE9Y7wWZ?p=preview Hope it will solve your problem.
Before rendering JSON data make it sure the format is correct.
here is the online json parser https://jsonformatter.curiousconcept.com/
Let me know then if it solve your issue.
Thanks

Related

Is there any way to make array json object display in HTML elements by using Angularjs

NOT able to display json object data on table.
JSON
{"json1":"[{\"years\":2018},{\"years\":2017},{\"years\":2016},{\"years\":2015}]",
"json2":"[{\"year5\":47.5100,\"year4\":50.9300,\"year3\":68.3700,\"year2\":65.2500,\"year1\":0.0000,
\"reportFormula\":\" Total cost of sales/total sales \",\"reportRang\":\"<35%\",\"reportTypeDetail\":\"Cost of sales % of sales\"},
let app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
let result = {
data: {
"json1": "[{\"years\":2018},{\"years\":2017},{\"years\":2016},{\"years\":2015}]",
"json2": "[{\"year5\":47.5100,\"year4\":50.9300,\"year3\":68.3700,\"year2\":65.2500,\"year1\":0.0000,\"reportFormula\":\"Total cost of sales/total sales\",\"reportRang\":\"<35%\",\"reportTypeDetail\":\"Cost of sales % of sales\"}]"
}
}
$scope.yearList = result.data.json1;
$scope.dataList = result.data.json2;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<th ng-repeat="year in yearList[0].years"> {{year}}</th>
<th ng-repeat="year in yearList[0].years"> {{year}}</th>
<tr ng-repeat="data in dataList">
<td>{{data.reportTypeDetail}}</td>
<td>{{data.reportFormula}}</td>
</tr>
</table>
</div>
I found two mayor issues with your code. First, remember the golden rule: "Always parse your JSON object".
Why I need to parse my JSON? Well, when using the JSON.parse() on a JSON derived from an array, the method will return a JavaScript array, instead of a JavaScript object.
But what this means?
It means that JSON objects is represented as a JSON string which JavaScript cannot read directly.
Ok, then how can I parse it?
The Syntax is very simple JSON.parse(text), where text is the string to parse as JSON and it will return the Object corresponding to the given JSON text.
The ng-if directive and $index attribute
Now, you are using the following code to define your <th> tags:
<th ng-repeat="year in yearList[0].years"> {{year}}</th>
Which I think it is not correct, and limits your control of the values.
I think a better solution is if you combine the ng-repeat's $index attribute with the ng-if directive. Like this:
<th ng-repeat="year in yearList" ng-if="$index == 0"> {{year.years}}</th>
This will give you more control of the values and how you want to show them. This the working code for those modifications:
let app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
let result = {
data: {
"json1": "[{\"years\":2018},{\"years\":2017},{\"years\":2016},{\"years\":2015}]",
"json2": "[{\"year5\":47.5100,\"year4\":50.9300,\"year3\":68.3700,\"year2\":65.2500,\"year1\":0.0000,\"reportFormula\":\"Total cost of sales/total sales\",\"reportRang\":\"<35%\",\"reportTypeDetail\":\"Cost of sales % of sales\"}]"
}
}
$scope.yearList = JSON.parse(result.data.json1);
$scope.dataList = JSON.parse(result.data.json2);
console.log('yearList', $scope.yearList);
console.log('dataList', $scope.dataList);
});
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<th ng-repeat="year in yearList" ng-if="$index == 0"> {{year.years}}</th>
<th ng-repeat="year in yearList" ng-if="$index == 1"> {{year.years}}</th>
<tr ng-repeat="data in dataList">
<td>{{data.reportTypeDetail}}</td>
<td>{{data.reportFormula}}</td>
</tr>
</table>
</div>
Your JSON object contains two stringified json objects which JavaScript cannot directly read. To parse them use JSON.parse() like this:
JSON
{"json1":"[{\"years\":2018},{\"years\":2017},{\"years\":2016},{\"years\":2015}]",
"json2":"[{\"year5\":47.5100,\"year4\":50.9300,\"year3\":68.3700,\"year2\":65.2500,\"year1\":0.0000,
\"reportFormula\":\" Total cost of sales/total sales \",\"reportRang\":\"<35%\",\"reportTypeDetail\":\"Cost of sales % of sales\"},
JS
$scope.yearList=JSON.parse(result.data.json1);
$scope.dataList=JSON.parse(result.data.json2);
HTML
<th ng-repeat="year in yearList[0].years">{{year}}</th>
<th ng-repeat="year in yearList[1].years">{{year}}</th>
...
<tr ng-repeat="operation in dataList">
<td>{{operation.reportTypeDetail}}</td>
<td>{{operation.reportFormula}}</td>
.....
Your are using yearList[0] in your ng-repeat which returns an object like the following,
{"years":2018}
you can use
<div ng-repeat="(key, value) in yearList[0]">
{{key}},{{ value }}
</div>
to loop through your object or you can try the following to display the data from your list.
<div ng-repeat="item in yearList">{{item.years}}</div>
<br>
<div ng-repeat="operation in dataList">
{{operation.reportTypeDetail}}<br>
{{operation.reportFormula}}
</div>
Demo

How to set a class only to specific elements when using *ngFor?

I am using *ngFor to list table data: *ngFor="let record of records",
and I want to set custom css class to record based on some conditions, f.e. if record.name === something. Is this possible?
Yes, you on [ngClass] to achieve this, for example:
<div [ngClass]="{'record': record.name === 'something' }" *ngFor="let record of records">
you can try this way :
<ul class="r " *ngFor="let posto of posti">
<li [ngClass]="posto.id === something ? NewClass : oldclass" >
{{Something.id}}
</li>
</ul>
<tr *ngFor="let record of records">
<td [ngClass]="record.name === 'something' ? 'classForSomething' : 'classForOthers' ">{{record.name}}</td>
</tr>

match parent and inner index within nested ng-repeats while passing duplicate values

I am trying to pass duplicate values in different formats but can not match parent and inner indexes hence I get Error: [ngRepeat:dupes]. that said, I pass object with multiple properties among which I have tags...see below
vm.hotels returns objects like below
0:object
tags:"tag1|tag2|tag3"
1:object
tags:"tag1|tag2|tag3"
vm.hTags is an array that matches each object like below
["tag1", "tag2", "tag3"]
within my controller I split tags and push then into an array within a loop which I pass to the view. this works as it should but I can not make it work with indexes within the view. below are nested ng-repeats
<li ng-repeat="item in vm.hotels track by $index">
<ul>
<li ng-repeat="tag in vm.hTags[$index]">
{{tag}}
</li>
</ul>
<li>
I tried to use vm.hTags[$parent.$index] but it does not work as duplicate error is thrown due to indexes. Perhaps I need to create some custom tracking property ?
The problem with nested ng-repeat is that is that if you use $index for both child and parent, it might conflict. In order to avoid it, we can use it by giving name. Like this
ng-repeat="(hotelIndex, item) in vm.hotels ..."
I don't know how you want to render it but here's a sample example of that:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.hotels = [{
tags: "tag1|tag2|tag3"
}, {
tags: "tag4|tag5|tag6"
}]
vm.hTags = [["tag1", "tag2", "tag3"], ["tag4", "tag5", "tag6"]]
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="MainCtrl as vm">
<div ng-repeat="(hotelIndex, item) in vm.hotels track by hotelIndex">
<div ng-repeat="tag in vm.hTags[hotelIndex]">
{{tag}}
</div>
<br>
</div>
</body>
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.hotels = [{
tags: "tag1|tag2|tag3"
}, {
tags: "tag4|tag5|tag6"
}]
vm.hTags = [["tag1", "tag2", "tag3"]];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<body ng-app="myApp" ng-controller="MainCtrl as vm">
<div ng-repeat="key in vm.hotels">
<div ng-repeat="tag in vm.hTags[$index]">
{{tag}}
</div>
</div>
<br>
<div ng-repeat="(key, value) in vm.hotels">
<div ng-repeat="tag in vm.hTags[key]">
{{tag}}
</div>
</div>
</body>
Please find the code change below,
<li ng-repeat="item in vm.hotels track by $index">
<ul>
<li ng-repeat="tag in vm.hTags[$index]">
{{tag}}
</li>
</ul>
<li>
Check and let me know.You made a syntax error

how to render json data into an unordered list with angularjs

I am trying to create an inventory section that reads from a json file on the server. I've seen how to do this in a table but haven't had much luck with making a an unordered list. This site is currently using angular 1.6.1
Sample data and html:
angular.module('App', [])
.controller('AppCtrl', function($scope) {
$scope.data = [
{"id": 0,
"vinNum": "blank-vin-num",
"manufacturer": "200",
"model": "BIKE",
"bodyType": "Cycle",
"yearOfVehicle": "2006",
"stockNum": "11101",
"colorExt": "GREEN",
"mileage": "1",
"dateEntered": "08/08/2007"},
];
});
<div class="container" ng-controller="AppCtrl">
<h1>Inventory</h1>
<ul>
<li ng-repeat="stuff in data">{{stuff.model}}</li>
<li ng-repeat="stuff in data">{{stuff.manufacturer}}</li>
<li ng-repeat="stuff in data">{{stuff.vinNum}}</li>
<li ng-repeat="stuff in data">{{stuff.bodyType}}</li>
<li ng-repeat="stuff in data">{{stuff.colorExt}}</li>
<li ng-repeat="stuff in data">{{stuff.yearOfVehicle}}</li>
<li ng-repeat="stuff in data">{{stuff.stockNum}}</li>
<li ng-repeat="stuff in data"> {{stuff.mileage}}</li>
<li ng-repeat="stuff in data"> {{stuff.dateEntered}}</li>
</ul>
Now this works there is no other vehicle, but once you add another vehicle there will be two vinNums(same thing for every line) together instead of being separate. I am new to using Angular to make a list like this so if someone could help guide me that would be awesome.
Problem area is usage of ng-repeat with li element to read the object property.
You can remove ng-repeat from li, and wrap it in a div like
<div ng-repeat="stuff in data">
<ul>
<li>{{stuff.model}}</li>
<li>{{stuff.manufacturer}}</li>
<li>{{stuff.vinNum}}</li>
<li>{{stuff.bodyType}}</li>
<li>{{stuff.colorExt}}</li>
<li>{{stuff.yearOfVehicle}}</li>
<li>{{stuff.stockNum}}</li>
<li>{{stuff.mileage}}</li>
<li>{{stuff.dateEntered}}</li>
</ul>
</div>
OR,
You can use nested ngRepeat, As $scope.data is an array, it can be iterated using ng-repeat="stuff in data" then in the second iteration you can iterate properties.
<div ng-repeat="stuff in data">
<ul>
<li ng-repeat="(key, value) in stuff">{{key}}:{{value}}</li>
</ul>
</div>
(function(angular) {
'use strict';
angular.module('docsIsolateScopeDirective', [])
.controller('Controller', ['$scope',
function($scope) {
$scope.data = [{
"id": 0,
"vinNum": "blank-vin-num"
}, {
"id": 1,
"vinNum": "vinNum2"
}];
}
]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="docsIsolateScopeDirective">
<div ng-controller="Controller">
<div ng-repeat="stuff in data">
<ul>
<li ng-repeat="(key, value) in stuff">{{key}}:{{value}}</li>
</ul>
</div>
</div>
</div>
You better group the item data inside only one "li" element at a time, let's say that every "li" should be every element in the list, not every property of the element.
Try something like this:
angular.module('App', [])
.controller('AppCtrl', function($scope) {
$scope.data = [
{"id": 0,
"vinNum": "blank-vin-num",
"manufacturer": "200",
"model": "BIKE",
"bodyType": "Cycle",
"yearOfVehicle": "2006",
"stockNum": "11101",
"colorExt": "GREEN",
"mileage": "1",
"dateEntered": "08/08/2007"},
];
});
<div class="container" ng-controller="AppCtrl">
<h1>Inventory</h1>
<ul>
<li ng-repeat="stuff in data">
<div>{{stuff.model}}</div>
<div>{{stuff.manufacturer}}
<div>{{stuff.vinNum}}</div>
<div>{{stuff.bodyType}}</div>
<div>{{stuff.colorExt}}</div>
<div>{{stuff.yearOfVehicle}}</div>
<div>{{stuff.stockNum}}</div>
<div>{{stuff.mileage}}</div>
<div>{{stuff.dateEntered}}</div>
</li>
</ul>
You can use a table to display it well formated with search and order
ngTable is nice for that : http://ng-table.com/#/
working example :
https://plnkr.co/edit/JNKBydXCLtxuvQykirUL?p=preview
1 HTML :
<!-- load script and css for ngtable -->
<link rel="stylesheet"; href="https://unpkg.com/ng-table#2.0.2/bundles/ng-table.min.css">
<script src="https://unpkg.com/ng-table#2.0.2/bundles/ng-table.min.js"></script>
<div ng-controller="AppCtrl">
<table ng-table="tableParams" class="table" show-filter="true">
<tbody>
<tr ng-repeat="row in $data">
<td data-title="'id'" filter="{id: 'text'}" filter-data="id" sortable="'id'">{{ row.id }}</td>
<td data-title="'manufacturer'" filter="{manufacturer: 'text'}" sortable="'manufacturer'">{{ row.manufacturer }}</td>
<td data-title="'model'" filter="{model: 'text'}" sortable="'model'">{{ row.model }}</td>
<td data-title="'yearOfVehicle'" filter="{yearOfVehicle: 'text'}" sortable="'yearOfVehicle'">{{ row.yearOfVehicle }}</td>
</tr>
</tbody>
</table>
</div>
2 JAVASCRIPT
// inject ngtable dependency : ngTable && NgTableParams
var app = angular.module('App', ['ngTable'])
.controller('AppCtrl', function($scope, $filter, $q, NgTableParams) {
var data = [{"id":0,"vinNum":"blank-vin-num","manufacturer":"200","model":"BIKE","bodyType":"Cycle","yearOfVehicle":"2006","stockNum":"11101","colorExt":"GREEN","mileage":"1","dateEntered":"08/08/2007"},{"id":1,"vinNum":"blank-vin-num 1","manufacturer":"300","model":"BIKE 1","bodyType":"Cycle 1","yearOfVehicle":"2007","stockNum":"11101","colorExt":"GREEN","mileage":"1","dateEntered":"08/08/2007"},{"id":2,"vinNum":"blank-vin-num 2","manufacturer":"400","model":"BIKE 2","bodyType":"Cycle 2","yearOfVehicle":"2008","stockNum":"11101","colorExt":"GREEN","mileage":"1","dateEntered":"08/08/2007"},{"id":3,"vinNum":"blank-vin-num 3","manufacturer":"500","model":"BIKE 3","bodyType":"Cycle 3","yearOfVehicle":"2009","stockNum":"11101","colorExt":"GREEN","mileage":"1","dateEntered":"08/08/2007" } ];
$scope.tableParams = new NgTableParams({page: 1, count: 10}, {data: data});
})

How to group and display the values in angular js

I have created a scope function like this
$scope.sample = [
{'SUPNAME':'AAA','SUPCODE':'22671','SLIPNO':'18384','DESG':'1','iv':'1'},
{'SUPNAME':'AAA','SUPCODE':'22671','SLIPNO':'18384','DESG':'2','iv':'2'},
{'SUPNAME':'AAA','SUPCODE':'22671','SLIPNO':'18384','DESG':'3','iv':'3'},
{'SUPNAME':'BBB','SUPCODE':'24603','SLIPNO':'26714','DESG':'1','iv':'4'},
{'SUPNAME':'BBB','SUPCODE':'24603','SLIPNO':'26714','DESG':'2','iv':'5'},
{'SUPNAME':'BBB','SUPCODE':'24603','SLIPNO':'26714','DESG':'3','iv':'6'},
]
I have to display by grouping with same SUPNAME,SUPCODE,SLIPNO. For example I have to display it like this.
SUPNAME:AAA SUPCODE=22671
DESG 1 DESG2 DESG 3
SUPNAME:BBB SUPCODE=24603
DESG 1 DESG2 DESG 3
So how can I create ng-repeat for this..Kindly give some solution.
i tried to create a Codepen for your case
grouped Codepen
<table class="table table-striped">
<tr><td>{{data1}}</td><td>{{data2}}</td></tr>
<tr ng-repeat="item in filteredsample = (sample | filter:{ SUPNAME: 'AAA'})">
</tr>
<ul ng-repeat="thing in filteredsample">
<li style = "float:left; margin:20px">DESG VALUE {{$index}} = {{thing.DESG}}</li>
</ul>
</div>
Hope this helps

Categories

Resources