Is it possible to limit the number of displayed items in a loop in AngularJs - angularjs

I have a list of categories and many questions which belongs to different categories.
{
"id": 5,
"description": "Does your site have Facebook?",
"question_category_id": 3
}
{
"id": 1,
"name": "Network",
"description": "Network"
}
<table ng-repeat="c in categories">
<thead>
<tr>
<th>{{ c.id }}. {{ c.description }}</th>
</tr>
</thead>
<tbody ng-repeat="q in questions | filter: { question_category_id: c.id } : true">
<tr>
<td>{{q.description}}</td>
</tr>
</tbody>
</table>
This is the code which displays all questions under a category.
But I want to loop through each of the categories and only display 1 question under one category by using AngularJs.
Is it possible ?
If yes, how?
Thank you.

You have a couple of possibilities here, check de documentation of ng-repeat (https://docs.angularjs.org/api/ng/directive/ngRepeat). For example if you only want to show the first question, you can check $first in ng-show on the tr-tag.
But be aware that this is only not showing the other questions of that category in the html, you still have retrieved all questions of that category from the server which is a waste of resources since you are only showing the first question.

If you really want to iterate over questions, then you could use $index.
<tbody
ng-repeat="q in questions | filter: { question_category_id: c.id } : true"
ng-show="$index == 0">
If not, but still you do not want to touch the JavaScript part, then'd I'd go around this using
<td>
{{ (questions | filter: { question_category_id: c.id } : true)[0].description }}
</td>

Related

ng-repeat dynamically create arrays for nested ng-repeats

Is it possible to have ng-repeat dynamically create arrays for nested ng-repeats?
I know this sounds silly, but I'm essentially looking for something like this, and hoping someone will tell me how terrible of an idea this is and present a better solution:
<tbody ng-repeat="row in myRows track by $index">
<tr>{{row.name}}</tr>
<tr ng-repeat="subRow in myRows$index>{{subRow.name}}</tr>
</tbody>
So the idea is that the first <tr> row actually has a button that will show the subRows once clicked. So once clicked (before it actually displays the rows), I'll create the array then, such as:
myRows0 = [{name:"Sub Row A", value:1},
{name:"Sub Row B", value:2}];
or if the second row was clicked, I'd create:
myRows1 = [{name:"Sub Row C", value:3},
{name:"Sub Row D", value:4}];
I'm assuming something like this won't work because ng-repeat needs to have the array created before it can create the DOM. Is that correct? But I'm not sure how else I'd be able to create something like this then using this table structure. Any help?
It is possible and in my opinion it is not a bad idea, for example you may want to load your subRow data only when user clicks on displaySubRow items if your subRow data is big or they are images, to avoid putting an unnecessary burden to your server or keep your users waiting.
Working Plunker
Sample Code
html
<table>
<tbody ng-repeat="item in data" ng-init="item.show = false">
<tr>
<td>
<button ng-show="item.show==false" ng-click="getRowSubItems(item)">Show</button>
<button ng-show="item.show==true" ng-click="item.show = false">Hide</button>
</td>
<td>
{{item.name}}
</td>
</tr>
<tr ng-show="item.show == true">
<td>
</td>
<td>
<div ng-repeat="subItem in item.cars">
{{subItem}}
</div>
</td>
</tr>
</tbody>
</table>
js
$scope.data =
[{"name":"Lex",
"age":43
},
{"name":"Alfred",
"age":30
},
{"name":"Diana",
"age":35
},
{"name":"Bruce",
"age":27
},
{"name":"Oliver",
"age":32
}];
$scope.getRowSubItems = function(item){
//you can also make a http call to get data from your server
item.show = true;
if(item.name == "Lex"){
$http.get('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
item.cars = response.data;
});
}
else{
item.cars = [ "Ford", "BMW", "Fiat" ];
}
}

AngularJS - Insert ng-repeat into another one between two TR

My question is - I think - pretty simple.
I have a table, a classic one. In this table, I want to display values of two arrays named networks and channels.
Each network in networks could contain channels but not all.
What I want is to display all the networks and their related channels.
In DIV or TD in TR it's simple but I can't do this with multiple TR.
Example :
<tr ng-repeat="network in networks">
<td>{{network.Name}}</td>
<td ng-repeat="channel in channels | filter: { networkId: network.networkId}">{{channel.Name}}</td>
</tr>
Works like a charm!
But I'm searching thing like this :
<tr ng-repeat="network in networks">
<td>{{network.Name}}</td>
<td ng-repeat="month in year">{{month.Name}}</td>
</tr>
<tr ng-repeat="channel in channels | filter: { networkId: network.networkId}">
<td>{{channel.Name}}</td>
<td ng-repeat="month in year">{{month.Name}}</td>
</tr>
But I know that is not the good code to do this :)
Someone know how to do that ?
I don't want to change the TABLE by DIV.
Kind regards !
Each ng-repeat has its own scope so your network is not available on the second TR repeat.
If you really want to stick with table, you can create a table inside your tr like this:
<tr ng-repeat="network in networks">
<td>{{network.Name}}</td>
<td ng-repeat="month in year">{{month.Name}}</td>
<td>
<table>
<tr ng-repeat="channel in channels | filter: { networkId: network.networkId}">
<td>{{channel.Name}}</td>
</tr>
</table>
</td>
</tr>

AngularJS ng-repeat get data from JSON

I got a problem on getting data from ng-repeat.
<tr ng-repeat="x in records">
<td>{{x.id}}</td>
<td>{{x.title}}</td>
<td>{{x.year}}</td>
<td>{{x.note}}</td>
</tr>
The {{x.id}} is the tt0013158 I want to get from the JSON.
Here is the JSON:
{"result":{
"tt0013158":{
"note":"",
"title":"The Frozen North",
"year":"1922"
},
"tt1605783":{
"note":"",
"title":"Midnight in Paris",
"year":"2011"
}
}}
I can get the note, title and year correctly. But how can I get the id (such as tt0013158) from the JSON?
There is no notion in javascript (or angular) that tt0013158 in the sample above would be the object's id. It's just a key in a map.
I believe this should do the trick:
<tr ng-repeat="(key, x) in records.result">
<td>{{key}}</td>
<td>{{x.title}}</td>
<td>{{x.year}}</td>
<td>{{x.note}}</td>
</tr>
you need to use (key,value) syntax :
<tr ng-repeat="(key, value) in data in records.result">
<td>{{key}}</td>
<td>{{value.id}}</td>
<td>{{value.title}}</td>
<td>{{value.year}}</td>
<td>{{value.note}}</td>
</tr>
You can use following approach to iterate through ng-repeat
<tr ng-repeat="item in records">
<td>{{item.id}}</td>
<td>{{item.note}}</td>
<td>{{item.title}}</td>
<td>{{item.year}}</td>
</tr>

Different row for each unit

I have a nested array list and I would like to get a different table row for every unit.
JSON:
[
{
"id":1,
"units":[
{
"id":1,
"name":"Test 1",
},
{
"id":2,
"name":"Test 2"
}
]
}
]
So Test 1 and Test 2 should be in different table rows.
HTML:
<tr ng-repeat="user in users">
<td><p ng-repeat="unit in user.units">{{unit.name}}</p></td>
</tr>
The above code works but I am getting unit names in the same row.
I tried:
<tr ng-repeat="unit in users.units">
<td>{{unit.name}}</td>
</tr>
But that doesn't work. Any help will be appreciated!
Here's a solution that won't require any changes to your data, though it may not be the cleanest solution. The other option (which I'm not going to write up) is to modify your data and flatten the data down to a single array or object containing all the units.
I'm going to make an assumption that you want your DOM (including the <table>) to ideally look like this:
<table>
<tr>
<td><p>Test 1</p></td>
</tr>
<tr>
<td><p>Test 2</p></td>
</tr>
</table>
The problem here is there isn't anything that represents the "users" part of that first ng-repeat (2 ng-repeats are needed for this data structure). As far as I'm aware it's not possible to start an ng-repeat without also creating a DOM element (at least a temporary one), so we can create some valid html (<caption>s in this case) and have angular exclude it using a one-time binding ng-if.
<div ng-controller="MyCtrl">
<table>
<!-- The ng-if here will remove the <caption> from the end result. It's just a placeholder for the users repeater. -->
<caption ng-repeat-start="user in users" ng-if="::false"></caption>
<tr ng-repeat="unit in user.units">
<td><p>{{unit.name}}</p></td>
</tr>
<caption ng-repeat-end ng-if="::false"></caption>
</table>
</div>

AngularJS - Conditional filter in ng-repeat

This is my code:
<div ng-repeat="cat in categs | filter:searchText">
<div><h1 id="{{cat.id}}">{{cat.title}}</h1></div>
<table>
<tbody>
<tr ng-repeat-start="subcat in cat.data | filter:searchText">
<th><h2 id="{{cat.id}}_{{subcat.id}}">{{subcat.title}}</h2></th>
</tr>
<tr ng-repeat-start="subsubcat in subcat.data | filter:searchText">
<td><h3 id="{{cat.id}}_{{subcat.id}}_{{subsubcat.id}}">{{subsubcat.title}}</h3></td>
</tr>
<tr>
<th>Nombre</th>
<th>Descripcion</th>
<th>Enlace</th>
</tr>
<tr ng-repeat-end ng-repeat="item in subsubcat.data | filter:searchText">
<td>{{item.name}}</td>
<td>{{item.about}}</td>
<td>{{item.urltext}}</td>
</tr>
<tr ng-repeat-end>
<td></td>
</tr>
</tbody>
</table>
</div>
and the current filtering isn't working for what I want to do, that is:
If the title of h1,h2 or h3 matches searchText, then show everything nested inside (don't filter anything inside).
But if neither h1,h2 or h3 matches searchText but what's in the last ng-repeat-start matches something, filter only what matched.
To explain myself better, here is an example:
Vehicles
Cars
BMW
item1: green
item2: red
item3: black
Toyota
Bikes
If searchText is:
vehicles : it shows everything.
cars : it shows vehicles header and cars header(and everything under) but doesn't show bikes (unless the the text "cars" appears in some subheader inside bikes or in some item)
black : only shows Vehicles, Cars and BMW headers and only item3.
The problem of the current code is that, if I remove the filter from the last ng-repeat-start it does what I want to do in the cars example but doesn't work for the black example.

Resources