prevent ng-repeat from showing images when there is no data - angularjs

On most of our angular pages we got this annoying error and we cant seem to find a solution.
GET http://localhost:8080/img/flagNations/%7B%7B%20bookings.language%20%7D%7D.png 404 (Not Found)
The code is ok, and the error only appears when there is no data in ng-repeat.
vm.checkinTodayShowAll = false;
if (res.checkinToday.length) {
vm.checkinTodayShowAll = true;
vm.checkinToday = res.checkinToday;
}
and on the page I even hide it if there is no data...
<table class="start-table start-checkin-table" ng-show="vm.checkinTodayShowAll">
But still it wants to render that image
<tr ng-repeat="bookings in vm.checkinToday" class="start-text">
<td class="start-left start-border overflow">
<img src="./img/flagNations/{{ bookings.language }}.png" class="start-flag">
</td>
</tr>
How do we prevent it from trying to render the image when there is nothing to ng-repeat?

Use ng-if instead of ng-show:
<table class="start-table start-checkin-table" ng-if="vm.checkinTodayShowAll.length>0">
instead of:
<table class="start-table start-checkin-table" ng-show="vm.checkinTodayShowAll">
ng-show: Just hides the view It is still in DOM . ng-if: Remove
element from DOM

Use ng-if instead of ng-show
<table class="start-table start-checkin-table" ng-if="vm.checkinTodayShowAll.length > 0">
<tr ng-repeat="bookings in vm.checkinToday" class="start-text">
<td class="start-left start-border overflow">
<img src="./img/flagNations/{{ bookings.language }}.png" class="start-flag">
</td>
</tr>

Use ng-if
<tr ng-repeat="bookings in vm.checkinToday" class="start-text">
<td class="start-left start-border overflow">
<img src="./img/flagNations/{{ bookings.language }}.png" ng-if="vm.checkinToday.length > 0" class="start-flag">
</td>
</tr>

//Try this one and it will boost performance also
<table class="start-table start-checkin-table" ng-if="vm.checkinTodayShowAll.length">
<tr ng-repeat="bookings in vm.checkinToday track by $index" class="start-text">
<td class="start-left start-border overflow">
<img src="./img/flagNations/{{ bookings.language }}.png" class="starflag">
</td>

Related

Angular ng-repeat with ng-if not working on tr tag

In the below Div i am using ng-repeat across some data to populate a list. while doing this i would like to NOT have a a certain TR tag created if it fits a certain requirement by using the ng-if directive on x.Equipment_Cost_Child != 0 However regardless of the expression I can't get the ng-if to work properly.
How can i get it to only show the TR if x.Equipment_Cost_Child > 0 ?
I have tried "x.Equipment_Cost_Child > 0"
I have also attached the ng-if directly to the tr tag instead of a div tag.
what do you think?
<div ng-repeat="x in reservationdata" ng-click="customerClickedEvent(x.ID)">
<table class="unit">
Item:{{$index + 1}}
<tr>
<td style="font-weight:bold">Equipment Type: </td>
<td style="font-weight:bold">{{x.EquipmentType}}</td>
</tr>
<tr>
<td style="font-weight:bold" >Equipment Count: </td>
<td style="font-weight:bold">{{x.Equipment_Count}}</td>
</tr>
<tr>
<td>Adult Quantity: </td>
<td>{{x.Equipment_Count_Adult}} Cost # ${{x.Duration_Cost_Adult}}</td>
</tr>
<div ng-if="x.Equipment_Cost_Child != 0"> //this line doesn't work
<tr>
<td>Child Quantity: </td>
<td>{{x.Equipment_Count_Child}} Cost # ${{x.Duration_Cost_Child}}</td>
</tr>
</div>
<tr>
<td>Sending Letters: </td>
<td> {{x.Equipment_Form_Status}}</td>
</tr>
<td> Total Cost For Item: </td>
<td> ${{(x.Equipment_Count_Adult * x.Duration_Cost_Adult)+(x.Equipment_Count_Child * x.Duration_Cost_Child)}}
Use both ng-if and ng-repeat within one tag:
<tr ng-repeat="feature in features"
ng-if="feature.id === 1" >
</tr>
Or, if you want to conditionally display some templates you may use ng-switch for example:
<tr
ng-repeat="feature in features"
ng-switch="feature.id" >
<span ng-switch-when="1"></span>
<span ng-switch-when="2"></span>
</tr>
Replace:
<div ng-if="x.Equipment_Cost_Child != 0"> //this line doesn't work
<tr>
<td>Child Quantity: </td>
<td>{{x.Equipment_Count_Child}} Cost # ${{x.Duration_Cost_Child}}</td>
</tr>
</div>
By:
<tr ng-show="x.Equipment_Cost_Child > 0">
<td>Child Quantity: </td>
<td>{{x.Equipment_Count_Child}} Cost # ${{x.Duration_Cost_Child}}</td>
</tr>
<div> tag is breaking your <tr> list. You can use ng-if directly on <tr>.
EDIT: use ng-show or ng-hide to show/hide elements. It is much lighter weight, because ng-if triggers a DOM recompilation and generates a new scope.

Ng-if to show and hide td data

Attached is my code, tried showing td data when the condtion of ng-if is true
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<div ng-repeat="value in data_report"
ng-if="(fellow.F_Id==value.fellowship_id)? (show_row = true) : (show_row=false)">
<td ng-show="show_row">{{value.Completed}}</td>
<td ng-hide="show_row">0</td>
<td ng-show="show_row">{{value.Not_Updated}}</td>
<td ng-hide="show_row">0</td>
<td ng-show="show_row">{{value.Total_schedule}}</td>
<td ng-hide="show_row">0</td>
</div>
</tr>
</tbody>
Its just giving 0 as result. Though data_report is having values
Tried adding span in td with conditions in td and result in span.
still the result is zero
May I know where the logic is going wrong and how it can be achieved?
Changed the code to
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<td>
<span ng-repeat="value in data_report" ng-show ="fellow.F_Id==value.fellowship_id">{{value.Completed}}</span>
</td>
<td>
<span ng-repeat="value in data_report" ng-show="fellow.F_Id==value.fellowship_id">{{value.Not_Updated}}</span>
</td>
<td>
<span ng-repeat="value in data_report" ng-show="fellow.F_Id==value.fellowship_id">{{value.Total_schedule}}</span>
</td>
</tr>
</tbody>
Here i am getting values but how can i set default value to zero if there are no values present?
In your case ng-if returns no boolean
The usage is (DOCs):
<ANY
ng-if="expression">
...
</ANY>
I think you dont need ng-if at all. You can write something like:
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<div ng-repeat="value in data_report">
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Completed: 0}}</td>
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Not_Updated: 0}}</td>
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Total_schedule: 0}}</td>
</div>
</tr>
</tbody>
Its not best solution, in Javascript you can set for example value.Completed to be by default 0. It will help you to simplify your HTML

Trigger ngInfiniteScroll correctly when using a scrolling table

I have a table inside a bootstrap-modal which has overflow set to auto so that it scrollable. However I need to load a lot of data so I would like to implement lazy-loading using ngInfiniteScroll. I have tried using the infinite-scroll-container attribute but it's still triggering constantly. Here is a code-snippet:
<div class="modal-body">
<table class="table" id="msds-table" ng-show="vm.modalViewLoaded" infinite-scroll="vm.log()" infinite-scroll-container='"#msds-table"'
infinite-scroll-disabled="!vm.modalViewLoaded">
<thead>
<tr>
<th>CODE</th>
<th>TYPE</th>
<th>PRODUCT</th>
<th>ONBOARD</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sheet in vm.datasheets | filter:onboardQuery | filter: (notOnBoardOnly ? {onboard:false} : {onboard:any})">
<td>{{sheet.code}}</td>
<td>{{sheet.type}}</td>
<td>{{sheet.product}}</td>
<td>
<span class="checkbox">
<input type="checkbox" data-ng-model="sheet.onboard" data-ng-value="sheet.onboard">
</span>
<span data-ng-show="!sheet.onboard">Click to select</span>
<us-list-select ng-model="sheet.located"
data-ng-show="sheet.onboard"
options="{list:vm.storageLocations}">
</us-list-select>
</td>
</tr>
</tbody>
</table>
<div ng-show="!vm.modalViewLoaded" style="text-align:center;padding-top:20px;">
<img src="images/ajax-loader.gif">
</div>
</div>
Any ideas?

AngularJS(1.3.0-rc.2): data-ng-repeat-end animation issue

Im wondering why an animation will not work on the <tr> element in this case (plnkr):
<tr data-ng-repeat-end data-ng-show="employee.show" class="animate-show">
<td colspan="5">
<div class="employeeInfo">
<img ng-src="http://placehold.it/{{employee.size}}" />Employee info
</div>
</td>
</tr>
But will work on the <td> element when written like this (plnkr):
<tr data-ng-repeat-end ng-animate-children>
<td colspan="5" data-ng-show="isToggled[$index]" class="animate-show">
<div class="employeeInfo">
<img ng-src="http://placehold.it/{{employee.size}}" />Employee info
</div>
</td>
</tr>
Why is this happening, and what can be done to achive animation on the <tr> with data-ng-repeat-end attribute?

AngularJS ng-include finished

I'm loading a large amount of data using ng-include.
I'd like to know if there is a way to know when a template is "rendered", because sometimes it seems like it's been "frozen", because I want to do a "loading screen" or something.
Thx.
Here's the code
controller code:
$scope.layout = {
current: 'single-table.html'
};
$scope.layout.get = function() {
return $scope.layout.current;
};
templates:
main.html
<div class="btn-group">
<button ng-click="layout.current = 'single-table.html'">Single</button>
<button ng-click="layout.current = 'multiple-table.html'">Multiple</button>
</div>
<div ng-include="layout.get()"></div>
single-table.html
<table class="table table-bordered">
<thead>
<th ng-repeat="column in columns">{{ column.title }}</th>
</thead>
<tbody>
<tr ng-repeat="record in records">
<td ng-repeat="field in record.fields"
ng-controller="FieldController"
ng-class="getClass()">
{{ field.display }}
</td>
</tr>
</tbody>
</table>
multiple-table.html
<table class="table table-bordered" ng-repeat="record in records">
<tbody>
<tr ng-repeat="field in record.fields">
<th>{{ columns[$index].title }}</th>
<td ng-controller="FieldController" ng-class="getClass()">
{{ field.display }}
</td>
</tr>
</tbody>
</table>
EDIT
I'm using version 1.2.0
One solution (probably not the best) is doing this (no ng-include)
<table class="table table-bordered" ng-show="layout.current == 'single-table.html'">
<thead>
<th ng-repeat="column in columns">{{ column.title }}</th>
</thead>
<tbody>
<tr ng-repeat="record in records">
<td ng-repeat="field in record.fields"
ng-controller="FieldController"
ng-class="getClass()">
<span lud-run="{{ field.ng_directive }}"></span>
</td>
</tr>
</tbody>
</table>
<table class="table table-bordered" ng-repeat="record in records" ng-show="layout.current == 'multiple-table.html'">
<tbody>
<tr ng-repeat="field in record.fields">
<th>{{ columns[$index].title }}</th>
<td ng-controller="FieldController" ng-class="getClass()">
<span lud-run="{{ field.ng_directive }}"></span>
</td>
</tr>
</tbody>
</table>
I have only 20 records, but (is not in the code), each cells loads a custom directive depends on the data type (string, date, datetime, image...). This "solution" I think runs the same data twice (ng-show, not ng-if), but when a switch the layout mode there is no "lag".
You can use the onload hook on ng-include to update a variable when the include has finished rendering. If you set it to true on clicking your button, then revert it back to false in onload, you should be able to leverage it to temporarily display a loading screen.

Resources