how to compare all the keys of object in js? - javascript

I need to compare all the selected attribute with variants on the AliExpress site.But my code is checking for only first key and adding class but when its come to 2nd and 3rd class its look like its not checking for them.I tried using length property but it says length is undefined.
function selectAttributes() {
chrome.storage.local.get(null, function(result) {
for (i = 0; i < result.ae_items.length; i++) {
console.log(result.ae_items[i].attributes);
for (var key in result.ae_items[i].attributes) {
$(".sku-property-list").each(function() {
$(".sku-property-item").each(function() {
if ($(this).has("img")) {
var title = $(this).children(".sku-property-image").children("img").attr("title");
if (title == result.ae_items[i].attributes[key]) {
$(this).addClass("selected");
}
} else {
var title = $(this).children(".sku-property-text").children("span").text();
alert(title);
}
});
});
}
}
});
}

This is comparing all the keys of object but the issue was with else block. Else block was not executing so I tried different ways and finally came out with decision that no need to use else block. Its working after removing else block

Related

hasOwnProperty() is only checking if a certain property exists in a JSON, but doesn't return anything if it doesn't

I keep trying different methods to check if this JSON contains "attributes." In this way I can determine if the given coordinates are outside of wetlands. If they are in wetlands, "attributes" will exist in the JSON. If they aren't in wetlands, 'attributes' won't be in the JSON.
When I run this function, I am only getting TRUE - when I type in coordinates that are in a wetland (try 43.088 instead, in the JSON url, which returns true).
However I want FALSE for the given url. For some reason when I do console.log("FALSE"), this doesn't appear or return in the console at all if hasOwnProperty('attributes') == false.
Am I missing something?
function(GetData) {
fetch('https://www.fws.gov/wetlandsmapservice/rest/services/Wetlands/MapServer/0/query?where=&text=&objectIds=&time=&geometry=-88.305%2C43.060&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&relationParam=&outFields=WETLAND_TYPE&returnGeometry=false&returnTrueCurves=false&maxAllowableOffset=&geometryPrecision=&outSR=&returnIdsOnly=false&returnCountOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&gdbVersion=&returnDistinctValues=false&resultOffset=&resultRecordCount=&queryByDistance=&returnExtentsOnly=false&datumTransformation=&parameterValues=&rangeValues=&f=pjson&__ncforminfo=qCOZOO8Kyr4uogGcKvxkzzuK7gmavd4CxwTAkdbAsF2_aT4eeNbB0NpLwCYwiAJSf1ZHqY3CKVZ3osgMevhYGQrqRUQZej5oHaSmnSIaiZZb469Cexv-zqqmgYMuFJAAzrcRxvKXPBz9VnYPnMrM6kBNhO-cz6yK_w5T1mqNu_VXSbjBSihVf4_mlUBSVb9yf4C8scYXWm9Iak2Nfn1dtJACNUHLBHSElLvc1wxFMO2eUWNsD3qpCk3kAcRyYftuFU86n7THyk2IvkIUpxNmDHRxmmbgSYvPLMkl8t41Jzjp_bntkIyOWB0u8cQU2VsfASFUdznRkvrvYrQxgR8eyvsPq5oV_ZoPSksVCew6xev0K_TV2NU-kjojYpowMVXpZtCX9P-Q_7m8ywt2PyLPhEVgQB12ji1S7G5FRzIt6E0SDoXMY1vqQvPtedaNYbBCazXgs05L9DFKdtvrwmQVCeLmpBTduIhF9Sk4kozMnFX6GOANrZJMCI9AssN0DjrhlZkgDVw0l1flF44Zli927CXGTQ-oUpwsn7PPypVkN2iDJf-nz9XNbj82sv1c6B5s5UZVwiOp8VHJfZSDJ8BAYR4z_oONT2JwbVSKKlFKeN72f-Y6EejcB9wPKmn5kYjv7CKkRyIIv4F4cqVWxLK9x33uvEDMTvxX')
.then(function(response) {
return response.json();
})
.then(function(data) {
appendData3(data);
})
.catch(function(err) {
console.log('error: ' + err);
});
function appendData3(data) {
for (let obj of data['features']) {
if (obj.hasOwnProperty('attributes') == false) {
console.log("FALSE");
} else {
console.log("TRUE");
}
}
}
};
The issue is that in the response data['features'] is empty. When iterating over an empty array, nothing within the for...of loop is executed.
const emptyArray = [];
for (const item of emptyArray) {
// body is never executed...
}
If just checking the presence of an item within data['features'] is enough, you could use the length of the array.
function appendData3(data) {
if (data.features.length > 0) {
console.log("TRUE");
} else {
console.log("FALSE");
}
}
To check if one of the elements has the property "attributes" you could use some():
function appendData3(data) {
if (data.features.some(item => item.hasOwnProperty("attributes"))) {
console.log("TRUE");
} else {
console.log("FALSE");
}
}
If you're just trying to find out if a specific point is within one of the wetlands polygons, you could let the server to do the hard job and simplify your request. For example, ask for count.
See returnCountOnly at https://developers.arcgis.com/rest/services-reference/enterprise/query-feature-service-layer-.htm
https://www.fws.gov/wetlandsmapservice/rest/services/Wetlands/MapServer/0/query?geometry=-88.305%2C43.060&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&returnCountOnly=true&f=pjson
https://www.fws.gov/wetlandsmapservice/rest/services/Wetlands/MapServer/0/query?geometry=-88.305%2C43.088&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&returnCountOnly=true&f=pjson
I tested your code and this is the problem. When the coordinates are outside the wetlands, the features array is empty, that means nothing happen in your for loop. So do this instead of checking directly inside of your for loop
function appendData3(data) {
// Here we check if features is empty by checking it's length
if (data['features'].length == 0) {
console.log("FALSE")
}
for (let obj of data['features']) {
console.log("TRUE");
}
}
I also see that your for loop is only getting one object every time so instea of doing a for loop, just do it like this:
function appendData3(data) {
var obj = data['features'][0]
if(obj) {
console.log('TRUE')
} else {
console.log('FALSE')
}
}
As you can see, I did it even easier this time, just by getting the first object of features and checking if it exist.
Also, small tip: when you want to check if a condition is false, don't use == false, just put an exclamation mark at the beginning of the if statement. Like that:
if(!obj.hasOwnProperty('attributes')) { 
// Code here will be executed if the condition is false
} else {
// Code here will be executed if the condition is true
}
I hope this help you fixing your problem.
Have a nice day :)

add/removeClass for array display - sonarqube

i am analyzing my code using sonarqube and coming across an error in the following function:
$(function () {
$("#SSNCollection input[type=text]").keydown(function (evt) {
var IsNullEmptyText = "true";
var ssntxtArrayText = [];
var txtLength = 0;
$("#SSNCollection input[type=text]").each(function () {
var _tempValues = $(this).val().toString().replace(/[-]/g, '').trim();
if (!isNaN(this.value.toString().replace(/[-]/g, '').trim())) {
var _temptxtlength = this.value.toString().replace(/[-]/g, '').trim().length;
ssntxtArrayText.push(_tempValues);
}
});
$.each(ssntxtArrayText, function (index, value) {
if (value.length >= 0) {
$('#resultValidation').css({
'display': 'none',
});
return false;
} else {
$("#resultValidation").removeAttr("style");
}
});
});
});
the issue starts with the if (value.length >= 0) {. because an array length will always be >=0 the if and the following else are unnecessary.
thus i changed the statement to
$.each(ssntxtArrayText, function (index, value) {
$('#resultValidation').css({
'display': 'none',
});
return false;
});
my issue now is that i'm being told that i should use addClass('hidden') and removeClass('hidden')as i may need the else statement after all. but i'm not sure how i'd utilize those in this case. any ideas? thanks!
The hidden class is typically included in CSS frameworks such as Bootstrap. If you are not using Bootstrap (or you aren't sure), simply add the following CSS to your project css file.
.hidden { display:none!important; }
or inline html version
<style>.hidden { display:none!important; }</style>
On the note of using conditional logic - after reviewing your code, I can confirm that the value variable does not return an array. It does in fact return a string value which means that checking if the length is greater than or equal to 0 is appropriate. If you want to check the array length before running the $.each, simply wrap the $.each in an if(ssntxtArrayText.length > 0) statement. The following example shows proper implementation of using .addClass() & .removeClass() and checking if the array has any values before running.
if(ssntxtArrayText.length > 0) {
$.each(ssntxtArrayText, function (index, value) {
if (value.length >= 0) {
$('#resultValidation').addClass('hidden'); //hide
return false;
} else {
$("#resultValidation").removeClass('hidden'); //unhide
}
});
}
Note: If you are checking for valid social security numbers, I recommend ensuring that the value has a length of 9 characters. This would be done like so: if (value.length == 9) {

how to check the presence of the element in the array?

please help solve the problem.
live example is here: https://jsfiddle.net/oqc5Lw73/
i generate several tank objects:
var Tank = function(id) {
this.id = id;
Tank.tanks.push(this);
}
Tank.tanks = [];
for (var i = 0; i < 3; i++) {
new Tank(i);
}
Tank.tanks.forEach(function(tank, i, arr) {
console.log(tank);
});
console.log('summary tanks: ' + Tank.tanks.length);
after i delete tank with random index:
var tankDel = Math.floor(Math.random() * (3));
Tank.tanks.splice(tankDel, 1);
Tank.count -= 1;
Tank.tanks.forEach(function(tank, i, arr) {
console.log(tank);
});
console.log('summary tanks: ' + Tank.tanks.length);
i try check tanks massive. if tanks massive contain tank with property 'id' = 0 then i need display alert('tank with id 0 is dead').
but console output follow error message:
Uncaught SyntaxError: Illegal break statement
break is to break out of a loop like for, while, switch etc which you don't have here, you need to use return to break the execution flow of the current function and return to the caller. See similar post here: illegal use of break statement; javascript
Tank.tanks.forEach(function(tank, i, arr) {
if(tank.id == 0) {
tank0Dead = false;
return;
};
});
if(tank0Dead == true) {
alert('tank with id 0 is dead');
};
jsfiddle : https://jsfiddle.net/oqc5Lw73/6/
You can't quit from forEach using break. Just remove break, and it will work.
P.S: honestly, it is better to refactor that code:)
Your only problem is that you can't use the break; statement in a forEach function.
But you can in a for() loop, so here is the equivalent code with a for :
for (var i = 0; i < Tank.tanks.length; i++){
if (Tank.tanks[i].id == 0){
tank0Dead = false;
break;
}
}
https://jsfiddle.net/oqc5Lw73/5/
But I agree with #dimko1 about the idea of refactoring the code
You can not break a forEach callback, simply because it's a function.
Here's updated working jSfiddle
If you really want to break it, you can use exception like code below.
try {
[1,2,3].forEach(function () {
if(conditionMet) {
throw Error("breaking forEach");
}
});
} catch(e) {
}
Otherwise you can use jQuery's each() method. when it's callback returns false it stops.
jQuery.each([1,2,3], function () {
if(conditionMet) {
return false;
}
});

Underscore reject Function with IndexOf removes all objects from array

I have a small Angular app that I'm writing that makes use of Underscore to look over each object in an array, and remove the object if it does not match the keyword (user input).
$scope.search = function() {
$scope.posts = _.reject($scope.posts, function(p) {
var i = 0;
if ($scope.keywords.indexOf(p.author) < 0 ) {
i++;
}
if ($scope.keywords.indexOf(p.id) < 0 ) {
i++;
}
if(i > 0) {
return true;
}
});
};
As you can see I'm setting a counter, and then adding to the counter if the keyword is found in the index, then at the end checking the counter to return true or false to remove the object from the array. $scope.posts is array of objects with my data and $scope.keywords is the user input. I'm wanting to lookup the input from $scope.posts.author object and $scope.posts.id object.
If I remove one of the if statements the function performs as expected: everything not matching the keyword is removed from the array. However, as soon as I add another if statement to the function (as seen in my example above), ALL objects are removed from the array.
It looks to me as though filter might be a better fit here:
$scope.posts = _.filter($scope.posts, function(p) {
return $scope.keywords.indexOf(p.author) > -1 || $scope.keywords.indexOf(p.id) > -1;
});
Working example: http://jsfiddle.net/4xp3sm10/
Instead of filter or reject it would be even easier to do it the opposite way using _.where
var newArray = _.where($scope.posts, {keyword : $scope.keyword});
There you go, one line.
Edit:
If you are stuck on doing it this way, here's a way you could clean it up a little.
$scope.posts = _.reject($scope.posts, function(p) {
var check = false;
if ($scope.keywords.indexOf(p.author) < 0 ) {
check = true;
}
if ($scope.keywords.indexOf(p.id) < 0 ) {
check = true;
}
if(i > 0) {
return check;
}
});
};
No need to use an integer like that
Since you are rejecting rows you will want to make sure ALL conditions are true. Your code is just checking for either one to be true.
$scope.search = function() {
$scope.posts = _.reject($scope.posts, function(p) {
return (
($scope.keywords.indexOf(p.author) < 0 ) &&
($scope.keywords.indexOf(p.id) < 0 )
);
});
};

How do I check if a property exists in an object/dictionary?

I'm iterating over an array of words and trying to stuff them in an object literal so I can assign the value of how many times those words occur to each word in the literal/dictionary. The problem is I need to check to make sure that word hasn't already been added into my literal. I tried using in to check if the property exists in the literal but it's throwing an error:
Cannot use 'in' operator to search for 'We' in undefined
Here's problematic function:
I commented the line that's causing the problem
function wordCountDict(filename) {
wordCount = {};
inputFile = fs.readFile( root + filename, 'utf8', function( error, data ) {
if(error) {
console.log('error: ', error)
return false;
}
var words = data.split(" ");
for (i in words) {
if(words[i] in wordCount) { // This is where the problem occurs
wordCount[words[i]]++;
} else {
wordCount[words[i]] = 1;
}
console.log(words[i]);
}
});
}
I'm coming from python and this was always the best/easiest way to achieve this, but javascript doesn't seem to agree.
How would I do this in JavaScript?
Declare wordCount as a local variable to that function. It is probably getting overwritten elsewhere:
function wordCountDict(filename) {
var wordCount = {};
...
}
This is a bad idea
for (i in words) {
do not use a for loop to loop through an array! If something is added to the array prototype it will be checked.
var words = data.split(" ");
for (var i=0; i<words.length; i++) {
if(words[i] in wordCount) {
Next thing, is readFile is asynchronous. If code outide of it resets wordCount to an undefined value, you can get this error. You are better off using a local variable and setting the global value when the looping is done. Also that return false does NOTHING inside the readFile.
function wordCountDict(filename) {
var tempWordCount = {};
var inputFile = fs.readFile( root + filename, 'utf8', function( error, data ) {
if(error) {
console.log('error: ', error)
return false;
}
var words = data.split(" ");
for (var i = 0; i<words.length; i++) {
if(words[i] in wordCount) { // This is where the problem occurs
wordCount[words[i]]++;
} else {
wordCount[words[i]] = 1;
}
console.log(words[i]);
}
wordCount = tempWordCount; //set the global variable equal to the local value
});
}
If all you would like to do is check for existance in the object, you can use this:
if(typeof wordCount[words[i]] === 'undefined'){
...
}
I would not recommend just using if(wordCount[words[i]]) because technically there could be a property of the object that exists but evaluates to false.
Note that in Javascript doing something like myObject.something is equivalent to myObject['something'] on an object, and that when you use myObject['somethingElse'] you are basically just dynamically adding members to the object. In Javascript, objects can be used like Python dictionaries, but they really aren't the same thing.

Categories

Resources