Check if a value is present in scope - angularjs

I have a scope called $scope.activities. Inside that scope are multiple objects. Each object has a string called viewed with the value of check or uncheck. I would like to check if the value uncheck is present in the scope.
I've created this, but it doesn't seem to work.
if (activities.indexOf("uncheck") == -1) {
console.log ('uncheck found')
$scope.newActivities = 'newActivities';
} else {
console.log ('no uncheck found')
}
Because in activities I have two objects, one with the uncheck value, and a object without it.
[{"id":2,", "viewed":"check"}, {"id":3,", "viewed":"uncheck"}]

You've got to loop each object and check the property - you can use Array.some
var hasValue = activities.some(function(obj) { return obj.viewed == "unchecked" });

You have to loop over each object in the array and test if the property "viewed" equal to "unchek"
var activities = [{"id":2, "viewed":"check"}, {"id":3, "viewed":"uncheck"}];
var activities2 = [{"id":2, "viewed":"check"}, {"id":3, "viewed":"check"}];
var check = function(data){
var checked = false;
for(var i in data){
if(data[i].hasOwnProperty("viewed") && (data[i]["viewed"]=="uncheck") ){
checked = true ;
}
}
return checked;
} ;
console.log(check(activities));
console.log(check(activities2));

Related

localStorage Array Objects - How to check is Object Key Value exists

How would i check to see if the ID exists within the localStorage object key array
i am currenty using this and it does not work
if (favorites.includes(theid)) { alert('You Allready Added this Listing'); }
Also how do i pull the indivdual object array apart into ID , image , title
to make varibles
Thank you
Below is the Full Code
function checkfave (theid) {
// get favorites from local storage or empty array
var favorites = JSON.parse(localStorage.getItem('favorites')) || [];
var theimage = $('#theimage'+theid).attr('src');
var thetitle = $('#thetitle'+theid).text();
if (localStorage.getItem('favorites') != null) {
if (favorites.includes(theid)) { alert('You Allready Added this Listing'); }
}
favorites.push({ID:theid,IMAGE:theimage,TITLE:thetitle});
localStorage.setItem('favorites', JSON.stringify(favorites));
alert('You Just Added Listing '+theid+' To Your Favorites');
//Loop through the Favorites List and display in console (HIDDEN)
console.clear();
for (let i = 0; i < favorites.length; i++) {
console.log('ID= '+favorites[i].ID+' IMAGE='+favorites[i].IMAGE+' TITLE='+favorites[i].TITLE);
}//for loop
}
When you parse json using JSON.parse, a javascript object is created. You can access keys in javascript objects by simply using the bracket notation:
object[key] = value
If a key is not defined in an object, when you request the key you will get undefined. undefined is equivalent to false when evaluating an if clause so you can simply use
if (favorites[theid]) { alert('You Allready Added this Listing'); }
I found a solution after the suggestions
My solution was to check within a for loop using favorites[i].ID == theid
The final code is below. i am very sure it could be done another way, But this works for now.
function checkfave (theid) {
var favorites = JSON.parse(localStorage.getItem('favorites')) || [];
var theimage = $('#theimage'+theid).attr('src');
var thetitle = $('#thetitle'+theid).text();
var added=true;
//Loop through the Favorites List and display in console (HIDDEN)
for (let i = 0; i < favorites.length; i++) {
if ( favorites[i].ID == theid ) { alert('You allready Added Listing '+theid+' To Your Favorites'); var added=false; break; } else {var added=true;}
}//for loop
if (added===true) {
favorites.push({ID:theid,IMAGE:theimage,TITLE:thetitle});
localStorage.setItem('favorites', JSON.stringify(favorites));
alert('You Just Added Listing '+theid+' To Your Favorites');
}
}

Infinite Digest Loop in AngularJS filter

I have written this custom filter for AngularJS, but when it runs, I get the infinite digest loop error. Why does this occur and how can I correct this?
angular.module("app", []).
filter('department', function(filterFilter) {
return function(items, args) {
var productMatches;
var output = [];
var count = 0;
if (args.selectedDepartment.Id !== undefined && args.option) {
for (let i = 0; i < items.length; i++) {
productMatches = items[i].products.filter(function(el) {
return el.Order__r.Department__r.Id === args.selectedDepartment.Id;
});
if (productMatches.length !== 0) {
output[count] = {};
output[count].products = productMatches;
output[count].firstProduct = items[i].firstProduct;
count++;
}
}
}
return output;
};
}).
This is the relevant HTML:
<tr class='destination' ng-repeat-start='pickupAccount in pickupAccounts | department : {"selectedDepartment": selectedDepartment, "option": displayExclusive }'>
<!-- td here -->
</tr>
displayExclusive is boolean.
I have written this custom filter for AngularJS, but when it runs, I get the infinite digest loop error.
Keep in mind that filter should return array of the same object structure. When we activate filter, it fires digest cycle that will run over our filter again. If something changed in output list - fires new digest cycle and so on. after 10 attempts it will throw us Infinite Digest Loop Exception
Testing
This empty filter will works (100%). Actually we do nothing here but return the same object that filter receives.
filter('department', function(filterFilter) {
return function(items, args) {
var output = items;
return output;
};
})
Now the main idea is: write some condition to push to output objects from input list a.e. items based on some if statement, a.e.
var output = [];
if (args.selectedDepartment.Id !== undefined && args.option) {
angular.forEach(items, function(item) {
if(<SOME CONDITION>) {
output.push(item);
}
});
}
By this way it will work too.
our case:
we have this logic:
productMatches = items[i].products.filter(function(el) {
return el.Order__r.Department__r.Id === args.selectedDepartment.Id;
});
if (productMatches.length !== 0) {
output[count] = {};
output[count].products = productMatches;
output[count].firstProduct = items[i].firstProduct;
count++;
}
Here we completely modified object that has been stored in output.
So next digest cycle our items will change again and again.
Conclusion
The main purpose of filter is to filter list and not modify list object content.
Above mentioned logic you wrote is related to data manipulation and not filter. The department filter returns the same length of items.
To achieve your goal, you can use lodash map or underscorejs map for example.
This happens when you manipulate the returned array in a way that it does not match the original array. See for example:
.filter("department", function() {
return function(items, args) {
var output = [];
for (var i = 0; i < items.length; i++) {
output[i] = {};
output[i] = items[i]; // if you don't do this, the next filter will fail
output[i].product = items[i];
}
return output;
}
}
You can see it happening in the following simplified jsfiddle: https://jsfiddle.net/u873kevp/1/
If the returned array does have the same 'structure' as the input array, it will cause these errors.
It should work in your case by just assigning the original item to the returned item:
if (productMatches.length !== 0) {
output[count] = items[i]; // do this
output[count].products = productMatches;
output[count].firstProduct = items[i].firstProduct;
count++;
}
output[count] = {};
Above line is the main problem. You create a new instance, and ng-repeat will detect that the model is constantly changed indefinitely. (while you think that nothing is changed from the UI perspective)
To avoid the issue, basically you need to ensure that each element in the model remains the 'same', i.e.
firstCallOutput[0] == secondCallOutput[0]
&& firstCallOutput[1] == secondCallOutput[1]
&& firstCallOutput[2] == secondCallOutput[2]
...
This equality should be maintained as long as you don't change the model, thus ng-repeat will not 'wrongly' think that the model has been changed.
Please note that two new instances is not equal, i.e. {} != {}

_.findWhere() is not giving result for property value undefined

I have a requirement to add new objects to an existing array of objects where duplicates are not allowed and the uniqueness of the objects is based on all the properties of the object. The object contains properties:
1. departmentId
2. equipmentId
3. sectionId
4. serviceId
According to my requirements, equipmentId is an optional field i.e. it may be undefined when there is no value for it. I wrote below for it:
$scope.isDuplicateRecord = function(){
var dupCheck = _.findWhere($scope.equipmentServiceMaps,{departmentId:$scope.equipmentServiceMap.department.departmentId,
equipmentId:$scope.equipmentServiceMap.equipment.equipmentId,
sectionId:$scope.equipmentServiceMap.section.sectionId,
serviceId:$scope.equipmentServiceMap.service.serviceId})
if(dupCheck== undefined){
return false
}else{
return true
}
}
This code is working fine with all values of quipmentId except undefined, i.e. if there is an existing object with the same departmentId, sectionId, serviceId and equipmentId as undefined. It's not finding that object and returning undefined hence My check is failing.
When I change to code to the basic for loop it worked, but I want to go ahead with the underscore. Below is my workaround code with for loop,
var dupCheck = undefined;
for(var i = 0; i < $scope.equipmentServiceMaps.length; i++){
if($scope.equipmentServiceMaps[i].departmentId == $scope.equipmentServiceMap.department.departmentId
&& $scope.equipmentServiceMaps[i].sectionId == $scope.equipmentServiceMap.section.sectionId
&& $scope.equipmentServiceMaps[i].serviceId == $scope.equipmentServiceMap.service.serviceId
&& $scope.equipmentServiceMaps[i].equipmentId == ($scope.equipmentServiceMap.equipment? $scope.equipmentServiceMap.equipment.equipmentId : undefined)){
dupCheck = $scope.equipmentServiceMaps[i];
console.log(dupCheck);
break;
}
}
if(dupCheck == undefined){
return false
}else{
return true
}
Please suggest how can I go ahead with the underscore.js
If you were looking for some syntactic sugar, this may help:
var search = {
departmentId:$scope.equipmentServiceMap.department.departmentId,
equipmentId:$scope.equipmentServiceMap.equipment.equipmentId,
sectionId:$scope.equipmentServiceMap.section.sectionId,
serviceId:$scope.equipmentServiceMap.service.serviceId
}
_.find($scope.equipmentServiceMaps, function(obj) {
return _.isMatch(_.defaults({}, obj, attrs), attrs);
})
The normal _.findWhere function works more or less like this:
_.find($scope.equipmentServiceMaps, function(obj) {
return _.isMatch(obj, attrs);
})
In my version, any undefined values in the object will be substituted by values from the search attrs. The original object is unmodified.

AsyncStorage.getItem returns undefined : React Native

Codeflow is-
I am checking if an entry called listobject exists in the AsyncStorage.
If it doesn't exist, then, I create an object, add few attributes and set the store. I get the store to obj as I have to compare in the next if condition.
If the listobject entry already exists(2nd time), then, it directly comes to the 2nd block, and compares. (The reason I get values to obj in 1st step is because I can have a common obj.data.isdirty condition.
Here is my code-
AsyncStorage.getItem('listobject').then((obj) => {
if(obj == undefined)
{
var obj1 ={};
obj1.data ={};
obj1.data.isdirty = true;
console.log("obj1 = "+ JSON.stringify(obj1));
AsyncStorage.setItem('listobject',obj1);
obj = AsyncStorage.getItem('listobject');
console.log("obj = "+ JSON.stringify(obj));
}
if(obj.data.isdirty)
{
obj.data.isdirty = false;
AsyncStorage.setItem('listobject',JSON.stringify(obj));
return AsyncStorage.getItem('listobject');
}
}).done();
I have 2 questions which are the outcome of the same issue-
Logs. I am setting obj1 and getting the same value for obj (so that I can compare the next if condition). Why am I not able to get the same value that I have set?
12-03 00:27:56.281 32598-487/com.abc D/ReactNativeJS: 'obj1 = {"data":{"isdirty":true}}'
12-03 00:27:56.286 32598-487/com.abc D/ReactNativeJS: 'obj = {"_37":0,"_12":null,"_59":[]}'
This is the end result of the above logs. I am getting that list.data.isdirty is undefined. I guess that because the JSON format I am accessing does not exist in obj i.e., obj.data.isdirty doesn't exist. So, how do I overcome this?
undefined is not an object (evaluating 'list.data.isdirty');
Please tell me what am I doing wrong?
I actually copied the object from one to another. It worked.
AsyncStorage.getItem('listobject').then((obj) => {
if(obj == undefined)
{
var obj1 ={};
obj1.data ={};
obj1.data.isdirty = true;
console.log("obj1 = "+ JSON.stringify(obj1));
AsyncStorage.setItem('listobject',obj1);
obj = obj1; //THIS IS WHAT I DID!
console.log("obj = "+ JSON.stringify(obj));
}
if(obj.data.isdirty)
{
obj.data.isdirty = false;
AsyncStorage.setItem('listobject',JSON.stringify(obj));
return AsyncStorage.getItem('listobject');
}
}).done();
I'm not quite following the entire question I do however see an issue with the use AsyncStorage. Going by the name, Async implies that the operations are asynchronous. So when you do getItem(key), you should either pass in a callback or use the Promise object it returns as you are doing in the first line of code.
obj = AsyncStorage.getItem('listobject');
console.log("obj = "+ JSON.stringify(obj));
obj is going to be the Promise in this case.
Then if you check on obj for the presence of a data and isDirty child property, they will not exist on the Promise.
Sometimes while doing console.log(AsyncStorage.getItem('Soomekey')) you will be getting undefined as you can't directly pull values from the AsyncStorage as returns a promise so what you should be writing is
const SomeFunction = async () => {
try {
const value = await AsyncStorage.getItem('somekey');
console.log(value);
} catch (err) {
console.log(err);
}
}

Checking if object is empty, works with ng-show but not from controller?

I have a JS object declared like so
$scope.items = {};
I also have a $http request that fills this object with items. I would like to detect if this item is empty, it appears that ng-show supports this... I enter
ng-show="items"
and magically it works,I would also like to do the same from a controller but i can't seem to get it to work, it appears I may have to iterate over the object to see if it has any properties or use lodash or underscore.
Is there an alternative?
I did try
alert($scope.items == true);
but it always returns false , when the object is created and when populated with $http, so its not working that way.
Or you could keep it simple by doing something like this:
alert(angular.equals({}, $scope.items));
In a private project a wrote this filter
angular.module('myApp')
.filter('isEmpty', function () {
var bar;
return function (obj) {
for (bar in obj) {
if (obj.hasOwnProperty(bar)) {
return false;
}
}
return true;
};
});
usage:
<p ng-hide="items | isEmpty">Some Content</p>
testing:
describe('Filter: isEmpty', function () {
// load the filter's module
beforeEach(module('myApp'));
// initialize a new instance of the filter before each test
var isEmpty;
beforeEach(inject(function ($filter) {
isEmpty = $filter('isEmpty');
}));
it('should return the input prefixed with "isEmpty filter:"', function () {
expect(isEmpty({})).toBe(true);
expect(isEmpty({foo: "bar"})).toBe(false);
});
});
regards.
Use an empty object literal isn't necessary here, you can use null or undefined:
$scope.items = null;
In this way, ng-show should keep working, and in your controller you can just do:
if ($scope.items) {
// items have value
} else {
// items is still null
}
And in your $http callbacks, you do the following:
$http.get(..., function(data) {
$scope.items = {
data: data,
// other stuff
};
});
another simple one-liner:
var ob = {};
Object.keys(ob).length // 0
If you couldn't have the items OBJ equal to null, you can do this:
$scope.isEmpty = function (obj) {
for (var i in obj) if (obj.hasOwnProperty(i)) return false;
return true;
};
and in the view you can do:
<div ng-show="isEmpty(items)"></div>
You can do
var ob = {};
Object.keys(ob).length
Only if your browser supports ECMAScript 5. For Example, IE 8 doesn't support this feature.
See http://kangax.github.io/compat-table/es5/ for more infos
if( obj[0] )
a cleaner version of this might be:
if( typeof Object.keys(obj)[0] === 'undefined' )
where the result will be undefined if no object property is set.
Or, if using lo-dash: _.empty(value).
"Checks if value is empty. Arrays, strings, or arguments objects with a length of 0 and objects with no own enumerable properties are considered "empty"."
Check Empty object
$scope.isValid = function(value) {
return !value
}
you can check length of items
ng-show="items.length"

Resources