AngularJS forEach function - cannot get to resolve to true - angularjs

I have the following code in my controller:
$scope.checkSchedule = function (value) {
var result = false;
angular.forEach($scope.shifts, function (obj) {
if (obj['PublishedEmployee.Id'] === value && result === false) {
result = true;
}
});
return result;
};
My $scope.shifts is an array of objects. Each object contains another object, PublishedEmployee and that object has a property of Id.
My goal is to iterate over the $scope.shifts objects and if the PublishedEmployee.Id property == $scope.currentId then resolve the function to be true.
In my HTML I have the following:
ng-show="checkSchedule(currentId)"
So, if the function resolves to true, the element will display. However, I'm always receiving false, what am I missing to have this resolve accordingly?
Pictures:

Your problem is that you are checking for the literal property "PublishedEmployee.Id" and not the sub property "Id" of "PublishedEmployee".
Change
if (obj['PublishedEmployee.Id'] === value && result === false)
to
if (!result && obj.PublishedEmployee && obj.PublishedEmployee.Id === value)
This will check for the existence of a PublishedEmployee property before attempting to compare its Id property.
If you're just wanting to check if any of the $scope.shifts match, you can use Array.prototype.some.
return $scope.shifts.some(function(obj) {
return obj.PublishedEmployee && obj.PublishedEmployee.Id === value;
});

In theory this will work if your data is as you say...
<div ng-repeat="item in shifts">
<div ng-show="item.PublishedEmployee.Id == currentId">
Matched
</div>
</div>

Related

Angular Filter controller filter default display all objects if no category is selected

html
ng-click="selectCategory(item)"
controller
$scope.selectCategory = function (newCategory) {
$scope.bottomValue = newCategory;
selectedCategory = newCategory;
$scope.selectedPage = 1;
}
$scope.categoryFilterFn = function (product) {
return selectedCategory == null ||
product.category == selectedCategory;
}
I have the category filter controller side below that's working fine and filtering the array correctly however when no category has been selected no objects are selected which is not desired
Objective : I want all values in the array to be displayed when no category is selected
e.g. note when $scope.bottomValue is removed from below all the objects in the array are returned.
$scope.edition_products = $filter('filter')( $scope.filteredItems, {approved: true, category: $scope.bottomValue});
Note: I no I can do this view side with filters but I want this working controller side.
You can update your condition to
return !selectedCategory || product.category == selectedCategory;
You might even want to add the approved there
return product.approved && (!selectedCategory || product.category == selectedCategory);

AngularJS - ng-if checking for true values when key is unknown

I want to apply a ng-if in AngularJS depending if any of the values in a JSON is true.
The first level keys are always the same, but then the second level keys are always different. (so I cannot do ng-if="known_stuff.unpredictable_thing", as the name of "unpredictable_thing" will be different each time. Here is the JSON.
{
"known_stuff":
{
"unpredictable_thing":false
},
"known_stuff_2":
{
"non_predictable_stuff":true
},
"known_stuff_3":
{
"something_unknown":false
}
}
Thanks in advance!
controller:
$scope.check = function(someObject) {
// return true if some value is true inside the object
for (var key in someObject) {
if (someObject[key] === true) {
return true;
}
}
return false;
};
template:
ng-if="check(known_stuff)"
or
ng-show="check(known_stuff)"
if your data is an array then the function has to look like that:
$scope.checkData = function(data) {
for (var i = 0; i < data.length; i++) {
for (var key1 in data[i]) {
// return true if some value is true inside the object
for (var key in data[i][key1]) {
if (data[i][key1][key] === true) {
return true;
}
}
}
}
return false;
};
template:
ng-if="checkData(data)"
If you want to check any of the value in your provided json is true then
ng-if="known_stuff.unpredictable_thing == ture ||
known_stuff_2.non_predictable_stuff == true ||
known_stuff_3.something_unknown == true"
If I got your question right, your json will have the first level key same (known_stuff) but inside know_stuff there can be multiple key with different names (like unpredictable_thing here).
The easiest solution is to iterate the first level key, gaining key value pair like below.
<div ng-repeat = "(key, val) in known_stuff" ng-if="known_stuff[key]">
//do something --> {{key}} - {{val}}
</div>
Supporting Plunk -> http://plnkr.co/edit/6hQQAtqRseb1gWvueFKr
-----------------------------------------------UPDATE---------------------------------------------
Assign jsonData with your data.
<div ng-repeat= "stuff in jsonData">
<div ng-repeat = "(key, val) in stuff" ng-if="stuff[key]">
//do something --> {{key}} - {{val}}
</div>
</div>
Also, updated the same plunk. I hope this answers your question.

AngularJS undefined, null and 0

Consider the following code:
<div ng-controller="SomeCtrl">
<div ng-show="someVariable.someProperty">Value of someProperty is set</div>
</div>
Now, when I set in my SomeCtrl controller:
$scope.someVariable.someProperty = 1;
It will show the div, as expected. But when I set:
$scope.someVariable.someProperty = 0;
It does not, while I only want to hide it in case $scope.someVariable.someProperty is either undefined or null. Of course I could write a simple Javascript helper-function to give me the expected result, or write something like:
<div ng-show="someVariable.someProperty || someVariable.someProperty == 0">Value of someProperty is set</div>
But isn't there a more elegant way to
handle this in AngularJS?
I only want to hide it in case $scope.someVariable.someProperty is either undefined or null
In JavaScript, undefined == null, but neither == 0. No need for extra functions or an extra conditional
ng-show="someVariable.someProperty != null"
Change your logic to be something more like this then:
ng-show="someVariable.someProperty !== null && someVariable.someProperty >= 0">
That way null or undefined will be falsy.
I almost forgot that null >= 0 === true (silly Javascript :)
Put a function in the controller like this:
$scope.shouldShow = function() {
if($scope.someVariable.someProperty === null ||
$scope.someVariable.someProperty === "undefined") {
return false;
}
return true;
}
and in the html:
<div ng-show="shouldShow()">Value of someProperty is set</div>
As mentioned by #tymeJV, "0" is evaluated as false in JS, so ng-show="0" will evaluate to hiding the div.
In SomeCtrl, you could write a function which encapsulates the logic to determine whether someProperty is null or undefined and return true or false based on that evaluation.
angular.module("app")
.controller("SomeCtrl", function($scope) {
$scope.someVariable = {};
$scope.someVariable.someProperty = null;
$scope.isNullorUndefined = function(value) {
return value === null || angular.isUndefined(value);
};
});
<div ng-show="!isNullOrUndefined(someVariable.someProperty)">Value of someProperty is set</div>

How to bind 1/0 instead of true/false on checked property of a checkbox

<input type="checkbox" data-bind="value : 1, checked: FgActive" />
I want FgActive to be 1 and 0 instead of true and false. Is there a simple way of doing that?
The easiest thing to do is to create a ko.computed that converts the checked boolean binding to/from a 1/0 numeric.
self.fgActiveNumeric = ko.computed({
read: function () {
return self.fgActive() == 1 ? true : false;
},
write: function (newValue) {
self.fgActive(newValue ? 1 : 0);
}
});
Use it like a normal checked binding:
<input type='checkbox' data-bind='checked: fgActiveNumeric' />
You can read more about this technique here: http://knockoutjs.com/documentation/computedObservables.html
See the Fiddle
I came across a solution. I created a custom binding that works on the update, after the checked binding. Dont know if is the best solution, but worked just fine.
ko.bindingHandlers.NumChecked = {
update: function (element, valueAccesor) {
var func = valueAccesor();
if (typeof (func) == 'function' && func() == true)
func(1);
else if ((typeof (func) == 'function'))
func(0);
}
};
<input type="checkbox" data-bind="NumChecked: FgActive, checked: FgActive" />
This is how I do it, using jQuery:
var myVal = ( $('#myCheckbox').is(':checked') ) ? 1 : 0;
alert('myVal is: ' +myVal); //alerts 1 if checked, 0 if not checked
jsFiddle Demo

How to filter ng-repeat on a child value using AngularJS

I've made a simple table with repeating rows based on an array using ng-repeat.
I've added a filter similar to this example.
My problem comes when I try to filter on the nested object. It is always a single object, basically it is the parent to my current object but it's the full object instead of just the FK value.
If I use filterText.educationCenter.name it filters all rows out of the table and will not return them even if I clear the filter. I have to do a full reload.
If I filter on just filterText.educationCenter it will work but it searches all fields of the entire object.
I would like to keep the JSON as it is and filter the table results based on the name of the educationCenter object.
My HTML
Search: <input ng-model="filterText.$"/>
<input ng-model="filterText.city"/>
<input ng-model="filterText.educationCenter.name"/>
<tr ng-repeat="course in courses | filter:filterText | startFrom:currentPage*pageSize | limitTo:pageSize">
<td width="145">{{course.city}}</td>
<td width="145">{{course.educationCenter.name}}</td>
...
My JSON for a singe object from the array
{"id":"108"
,"city":"My City"
,"educationCenter":{"id":"3"
,"description":"This is the ed center description"
,"name":"test ed center 1"}
,"noOfDays":"1"}
As #fastreload suggested, I think you'll have to make your own filter.
Here is the sample of the recursive filter.
(it does not support $ notation though, and I'm sure it is missing
some edge case support.)
app.filter('recursiveFilter', function() {
var compare = function(input_, cond_) {
if (!cond_) return true;
if (typeof input_ == "string" && typeof cond_ == "string") {
return (new RegExp(cond_)).test(input_);
} else if (typeof input_ == "object" && typeof cond_ == "object") {
for (var s in cond_) {
if (!compare(input_[s], cond_[s])) return false;
}
return true;
}
return false;
};
return function(inputs, cond) {
return $.grep(inputs, function(input) {
return compare(input, cond);
});
};
});

Resources