Data come from db , and this html element is a ng-repeat
{{count}}
My Question
How can i show if else condition that,
If count is null (nothing count value) I would show 0 (count value should be zero) , else show original count value
I hope there are solution like {{count if '' else ''}}
You could have have logic in your view with {{count || 0}} or {{ count ? count : 0 }} but this makes maintainability more difficult and duplicates logic.
A better option would be to create a custom filter. This will allow you to define you condition in a single place and makes it re-usable in many directives but also testable.
.filter('isEmpty', function() {
return function (data) {
return (data === null || data === undefined) ? 0 : data;
}
});
And you would use it like
{{item | isEmpty}}
See fiddle: http://jsfiddle.net/fhfsex4v/2/
EDIT: Here's the docs for filter that will explain what its doing and also how to pass optional extra parameters into your filters and other cool stuff.
https://docs.angularjs.org/guide/filter
How about {{ count ? count : 0 }}
Related
I have to sort data coming from the server dynamically by differents fields. It is working perfectly with all the fields except by time slot field. I have to sort data by time slot field in ascedening order, the problem is that the time slot is string e.g: "09:00-09:59".
My sorting function is:
function sortArray(array: any[], direction: string, extractor: (any) => any): any[] {
return array.sort((e1, e2) =>
(direction === 'asc' && extractor(e1) > extractor(e2)) || (direction !== 'asc' && extractor(e1) < extractor(e2))
? 1
: -1
);
}
How can I fix it? If anyone know then please let me know. Thank you.
Your sortArray function is fine. You have to check sort.active and sort.direction are updating correctly.
Try like this:
console.log('this.sort.active', this.sort.active);
console.log('this.sort.direction', this.sort.direction);
And If they are not updating then this is the problem. Then revise your logic of updating these things.
I created a filter that I want to pass an item property, and not the item itself. Is that possible?
The following does not work (item.param1 fails):
ng-reapeat="item in items | filter : fnFilter(item.param1)"
$scope.fnFilter = function(value) {
return value == "test";
}
Your question is quite unclear sdince you don't tell really what is your goal.
So if i just restrict to what i see there and following the link Angular filter exactly on object key already provided by #CeylanMumumKocabas you would have
ng-repeat="item in items | filter:{'param1': 'test'}"
Now let's consider you want something more complex : the only way i see would be to pass the name of the attribute to the filter :
ng-reapeat="item in items | myFilter:'param1'"
myApp.filter('myFilter', function () {
return function(inputs,attributeName) {
var output = [];
angular.forEach(inputs, function (input) {
if (input[attributeName] == 'test')
output.push(input);
});
return output;
};
});
Note that if you want to go more than one level, you'll have to use $eval or make add some code for this to work.
I was wondering what would be the best way to accomplish getting a substring of a value from a JSON object that is being spit out in an ng-repeat. Currently I have:
<tr data-ng-repeat=" item in records | orderBy : '-score' | limitTo : 10 " ng-click="moreInfo(item)">
<td>{{$index+1}}</td>
<td>{{item.name}}</td>
<td>{{item.score}}</td>
</tr>
And what is displayed on the page is user-SmithJoe. I was wondering if it is possible in the html to do something like {{item.name.substring(5,item.name.length())}}. I am sure that doesnt work, but hopefully you understand what I am trying to accomplish from that. I ultimately just want SmithJoe to be the output.
This is the js:
data2.forEach(function(r) {
if (r && r.user && r.user.toLowerCase().indexOf($scope.searchText.toLowerCase()) !== -1) {
$scope.records.push(r);
}
});
It the for each part is just going through all of the returned json objects and adding them to records[] if they contain what I am looking for. So since I did it this way I didn't really see there any way to take a substring # that point?
Thanks.
Add a property to the object when you iterate:
data2.forEach(function(r) {
if (r && r.user && r.user.toLowerCase().indexOf($scope.searchText.toLowerCase()) !== -1) {
r.prettyName = r.name.replace("user-", "");
$scope.records.push(r);
}
});
And output that name:
<td>{{item.prettyName}}</td>
{{item.name.slice(5)}}
should works :)
I'm printing out rows of a grid with Knockout js. I'd like my view to apply a CSS class based on wether or not the index of the iteration is divisible by 2.
This is my binding statement, called for each row:
<data-bind="css: { $index % 2 === 0 ? 'grid_row' : 'grid_a_row' }">
Two problems arises:
The use of % seems to be prohibited inside of an attribute
declaration. My IDE (VS2012) doesn't recognize anything which comes
after % as part of the string (I can see that by the difference in
the color)
Is this the correct way to apply one class or the other in
Knockout? Or do I have to write $index % 2 === 0 two times (one for each class)?
Which solutions are applicable?
Your syntax is slightly wrong. You have to use $index() % 2 === 0 and you are using the css binding incorrect. This will work:
<div data-bind="css: { grid_row: $index() % 2 === 0, grid_a_row: $index() %2 === 1 }">
http://jsfiddle.net/PYsc2/
Yes, you are correct:
Is this the correct way to apply one class or the other in
Knockout? Or do I have to write $index % 2 === 0 two times (one for each class)?
Your CSS binding syntax is incorrect, it should be:
css: { 'name-of-css-rule': function(){}, 'another-css-rule': function(){} }
In your case, you can make an observable like:
viewModel.myBooleanFunction = ko.computed(function() {
return this.foo() % 0 === 0 ? "even" : "odd";
}, viewModel);
and in your CSS binding declare it like this:
data-bind="css: myBooleanFunction"
Those are dynamic CSS rules:
From: http://knockoutjs.com/documentation/css-binding.html
Or if you prefer to use attr binding, you could use the coalesce operator like this.
data-bind="attr: { class: ($index() % 2 == 0) ? 'grid_row' : 'grid_a_row' }"
Please note that it will overwrite the class attribute completely and any other previously declared class will be lost.
If I have an expression {{ x }} and x is undefined or null, then how can I display a placeholder for it?
I provided one solution in my answer, but I would like to know what other ways there are.
Maybe, also for placeholder for promises.
{{ counter || '?'}}.
Just pure javascript. || can be used as default value. Since it would be different empty messages in each, a generalized directive would not be suitable for many cases.
If you want to apply a different class to empty ones, that's also built-in:
<div ng-class="{empty: !counter}" ng-bind="counter || ?"></div>
I would do it like this, but maybe there is a better way:
angular.module('app').filter('placeholdEmpty', function(){
return function(input){
if(!(input == undefined || input == null)){
return input;
} else {
return "placeholder";
}
}
});
and then use {{ x | placeholdEmpty}}
I do it with ng-show, like this:
<strong>{{username}}</strong>
<span class="empty" ng-show="!username">N/A</span>
Sure, it adds a lot more elements to my view that I might be able to handle differently. I like though how easy it is to clearly see where my placeholder/empty values are, and I can style them differently as well.
Implement default filter:
app.filter('default', function(){
return function(value, def) {
return (value === undefined || value === null? def : value);
};
});
And use it as:
{{ x | default: '?' }}
The advantage of the filter solution over {{ x || '?'}} is that you can distinguish between undefined, null or 0.
Implementing default-ish filters works, but if you're using only numbers you can use angular's own number filter
If the input is null or undefined, it will just be returned. If the
input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or
'-∞' is returned, respectively. If the input is not a number an empty
string is returned.
{{ (val | number ) || "Number not provided"}}