Looping over two arrays for each row in a table - javascript

I have the following set of json
[
{
"drink_name": "Ananascocktail",
"ingredients": [
"Ananas",
"Färskpressad limesaft",
"Apelsinjuice",
"Farinsocker",
"Rom"
],
"alternatives": [
"",
"Limesaft",
"",
"Socker",
null
]
},
{
"drink_name": "Blå Pilthammer",
"ingredients": [
"Blåbärsvodka",
"Apelsinjuice",
"Bonaqua Citron"
],
"alternatives": [
"Vodka",
"",
""
]
}
]
How do I loop over the ingredients and alternatives to place each element in separate <td>'s on the same <tr>?
I've tried putting a ng-repeat on the row, but that makes a new row for each element.
I must, however, use a ng-repeat on the <tr> since I have multiple ingredients/alternatives.
I've googled around for over an hour but can't find anything that quite fit my needs.
Any suggestions?

I solved it by doing the following
<tbody>
<tr ng-repeat="ingredient in json.ingredients">
<td>{{ingredient}}</td>
<td ng-repeat="alternative in json.alternatives track by $index" ng-if="$parent.$index === $index">{{alternative}}</td>
</tr>
</tbody>
I only allow alternatives to place a <td> if its $index is the same as its $parent's $index. Why that solved it is beyond me

Related

Looping through the json service response in Angular JS

I am working on a angular project. i have a scenario where i need to list some details in a page of the application.I have a service call in the page which returns the following json structure. i want to loop through this json structure to list few of the data in the response.
[
{
"ProductDetails": [
{
"ProductType": "Application1",
"Name": "Product1",
"New": false,
"Category": "product",
"Country": "India",
"description": "Description for Product1",
"Favourite": false,
"settings": {
"WebsiteFlag": true,
"SmsFlag": false,
"EmailFlag": true
}
}
]
},
{
"ProductDetails": [
{
"ProductType": "Application2",
"Name": "Product2",
"New": true,
"Category": "product",
"Country": "India",
"description": "Description for Product2",
"Favourite": true,
"settings": {
"WebsiteFlag": false,
"SmsFlag": false,
"EmailFlag": true
}
}
]
}
]
JS
$ctrl.getSettings = function () {
var url = "http://localhost:3000/json/settings-updated.json";
rsicontext.getData(url).then(function (response) {
$ctrl.Settings = response.data;
});
}
HTML
<tbody>
<tr data-ng-repeat="app in $ctrl.Settings" class="content-box">
<td data-ng-bind="app.ProductDetails.ProductType"></td>
<td data-ng-bind="app.ProductDetails.Name"></td>
<td><ng-checkbox data-checked="app.SmsFlag" rounded="true"></ng-checkbox></td>
<td><ng-checkbox data-checked="app.EmailFlag" rounded="true"></ng-checkbox></td>
</tr>
</tbody>
I am trying to list the Product Type, Name, EmailFlag and SmsFlag. How can i loop through the json structure to list the data.
Simply go over the response and build a new array from the fields you need. Like so:
var d = [];
for( vari=0;i< response.data.ProductDetails.length; ++i) {
var curr= {
ProductType: response.data.ProductDetails[i].ProductType,
Name: response.data.ProductDetails[i].Name
}
d.push(curr);
}
$ctrl.Settings = d;
To manipulate object or array I always use a library called underscore.js
This can help you to do what you want.
var plucked=_.pluck($ctrl.Settings, 'ProductDetails');
This function will return an array of object. Then you can loop it.
https://jsfiddle.net/wz2njukj/
You can achieve this throw ng-repeat
<div ng-repeat="d in data[0].ProductDetails[0]">
{{ d.SmsFlag }} {{ d.WebsiteFlag}} {{d.EmailFlag}}
</div>
Look this and get data as you want.
PlunkerHere
ProductDetails contains an array, so you would have to nest ngRepeats
<span data-ng-repeat="detail in app.ProductDetails">
If you know that ProductDetails will only have one element it would be best to change the structure that is being generated if you can. If not you can access it in markup
<tbody>
<tr data-ng-repeat="app in $ctrl.Settings" class="content-box">
<td data-ng-bind="app.ProductDetails[0].ProductType"></td>
<td data-ng-bind="app.ProductDetails[0].Name"></td>
<td><ng-checkbox data-checked="app.ProductDetails[0].settings.SmsFlag" rounded="true"></ng-checkbox></td>
<td><ng-checkbox data-checked="app.ProductDetails[0].settings.EmailFlag" rounded="true"></ng-checkbox></td>
</tr>
</tbody>
Or you can massage the data in your controller before passing it off to the view.
$ctrl.Settings = response.data.map(products=>products.ProductDetails[0])

Table with full month view with ng-repeat?

wanted to create a table just like this
(ignore the styling). i got confuse how to formate the data to make this table in html.
$scope.toddlers = [
{
"name": "a",
"day": 1,
"total": 3
},
{
"name": "b",
"day": 2,
"total": 4
},
{
"name": "c",
"day": 4,
"total": 1
}
];
i think i need to change my data format or something i just can't make this table right. how should i format my data to give this result.
FYI: i am getting my data by using mongodb aggregate.
plunker link
This snippet can produce the layout which you're desiring of:
<table border="1">
<tr>
<th></th>
<th ng-repeat="day in days">{{day}}</th>
</tr>
<tr ng-repeat="toddler in toddlers">
<td>{{toddler.name}}</td>
<td ng-repeat="day in days">
<span ng-if="toddler.day === day">{{toddler.total}}</span>
<span ng-if="toddler.day !== day">0</span>
</td>
</tr>
</table>
It first repeats the days in th, with one extra th before all of days. Then if current toddler's day matches the current day, it shows toddler.total, otherwise 0 using ng-if directive.

AngularJs dynamic table performance issues

I'm working on a project that requires a table to be dynamically constructed from an array of header objects:
[{ field: "name", show: true, title: "Name"},
{ field: "id", show: true, title: "ID"},
{ field: "time", show: true, title: "Time"}]
and an array of data objects that is updated at an interval:
[{ name: "Abc", id: 123, time: "300" },
{ name: "Def", id: 456, time: "10" }]
My template looks something like this:
<table class="table">
<thead>
<th ng-repeat="header in cols">
{{::header.title}}
</th>
</thead>
<tbody>
<tr ng-repeat="row in visibleData">
<td ng-repeat="col in cols">
{{::row[col.field]}}
</td>
</tr>
</tbody>
</table>
Please note that this is a simplified version but it holds the important bits.
As of now, rendering a table with 10 cols and 20 rows takes around 200ms (which creates a noticeable lag in scrolling and other page animations).
As you can see, I've tried to use one-time biding but that hasn't improved the performance noticeably.
Another thing I've tried was to 'track by' row.id, but this caused the data to stop updating altogether (The initial DOM object is reused even though some columns have changed).
So my question is, what measures should I take in order to optimize this configuration?
Any help would be greatly appreciated.
Thanks :)

Dust.js multi level array data

My JSON data looks something like this:
{
data:[
[
{"title": "Text1"},
{"title": "Text2"},
{"title": "Text3"}
],
[
{"title": "Text4"},
{"title": "Text5"},
{"title": "Text6"}
]
]
}
I want to use the data to generate a table. So far, I only manage to get it generate rows.
{#data}
<tr>
<td>{title}</td>
</tr>
{/data}
How can I get it generate columns? Thanks.
You need to add an extra loop as each value in the first array is also an array:
{#data}
<tr>
{#.}
<td>{.title}</td>
{/.}
</tr>
{/data}

Knockout table bindings with an object

I have a javascript object that I want to bind to a table using KnockoutJS
Here's my object:
var data = {
"Warnings": {
"numbers": 30,
"content": [
{
"number" : 3001,
"description" : "There may be a problem with the device you are using if you use the default profile"
},
{
"number" : 3002,
"description" : "There may be a problem with the device you are using if you don't use the default profile"
}
]
},
"Errors": {
"numbers": 20,
"content": [
{
"number": 1000,
"description": "No network is loaded"
},
{
"number": 1000,
"description": "No network is loaded"
}
]
}
};
ko.applyBindings(data);
Here's my html code:
<table class="table table-hover">
<thead>
<tr>
<th style="width:100px">Numero</th>
<th>Description</th>
</tr>
</thead>
<tbody data-bind="foreach: Warnings.content">
<tr data-bind="foreach: $data">
<td data-bind="text: $data.number"></td>
<td data-bind="text: $data.description"></td>
</tr>
</tbody>
</table>
Here's a JSFiddle: http://jsfiddle.net/etiennenoel/KmKEB/
I really need to use this format for my data Object.
I don't know why I'm not having the Warnings listed in a table since I'm not getting any errors...
You have an extra foreach that is not needed. Simply remove the foreach on your tr. The foreach on your tbody will assign a new value for $data for each tr that is rendered in the loop.

Categories