Javascript: What is wrong with this conditional? - javascript

I'm working on a Chrome extension an I've hit a wall.
function isInQueue(id) {
chrome.extension.sendRequest({getQueueItems: 1}, function(response) {
var items = response.items;
if (items) {
for (var i = 0; i < items.length; i++) {
if ((items[i].id == id) == true) return true;
}
return false;
} else { return false; }
});
}
The request returns 'items' which is an array of objects. I am trying to see if another item outside of the queue already exists inside the queue. For example, there is an item on the outside with an id equal to '198677'. I know I already have an exact copy of that same item in my queue with the exact same id, '198677', however, when I test the two for equality (items[i].id == id) == true, it returns false. I have checked the typeof both and they are both strings. I have tried using === and that hasn't worked. I tried adding zero to each of them to turn them into integers and that made the function return true when it was actually true, however, when I tested for true if (isInQueue(id) == true) the conditional returned false.
This is all very confusing and frustrating for me. They're both strings, why doesn't it work?
Help is very much appreciated.

The problem is chrome.extension.sendRequest is asynchronous - it returns immediately, but the callback function you provide to it will only be called once the request has completed.
The usual way to handle something like this is to pass a callback to your isInQueue method; the callback is called when the asynch operation is completed with the result.
function isInQueue(id, callback) {
chrome.extension.sendRequest({getQueueItems: 1}, function(response) {
var result = false;
var items = response.items;
if (items) {
for (var i = 0; i < items.length; i++) {
if ((items[i].id == id) == true) {
result = true;
break;
}
}
}
callback(result);
});
}

I figured it out:
function isInQueue(id) {
var result = false;
var queue = localStorage["queue_rss"];
if (queue != undefined) {
var items = JSON.parse(queue).items;
if (items) {
for (var i = 0; i < items.length; i++) {
if ((items[i].id == id) == true) {
result = true;
break;
}
}
}
}
return result;
}
I should have done it that way in the first place.
Thanks guys. :D

Related

Javascript function error : length undefined

I am a novice JavaScript user learning about how to code functions in a sustainable and clean way.
But I came across some problems and it throws an error such as console undefined or length undefined and I don't know why it happens like that.
//objects
var lists = [{
ignore: true,
accept: true
},
{
meaning: true
}
];
var start1 = processthings(lists, start);
if (!start1) {
console.log("wrong! start it first!")
};
var dictionary1 = processthings(lists, dictionary);
if (!dictionary1) {
console.log("look it up!")
};
//comprehensive process function
function processthings(lists, cfunctions) {
for (var i = 0; i < lists.length; i++) {
if (cfunctions(lists[i])) {
return true;
};
return false;
};
};
//each function : number 1
function start(element) {
return (element.ignore == true);
};
// each functon : number 2
function dictionary(element) {
return (element.meaning);
};
The for loop in function processthings will never iterate through the entire list. The function will always return after the first iteration.
I am not sure whether that is done intentionally or not. But I think the function should be modified as below -
//comprehensive process function
function processthings (lists,cfunctions){
var flag = false;
for (var i=0; i< lists.length; i++){
if (cfunctions(lists[i])){
flag = true;
break;
};
};
return flag;
};
See the working code here

Breaking from a recursive function and returning a value in Javascript

I have written a javascript function like this . But I want when a cretain condition meet the function will not execute means it will break and return a true false like status.My code is like this
var ActionAttributes = function (data)
{
var status = true;
var attrKey = data.AttributeKey();
//Condition to exit
if (attrKey==''||attrKey==null)
{
status = false;
return false;
}
for (var i = 0; i < data.Children().length; i++)
{
var childData = data.Children()[i];
ActionAttributes(childData);
}
return status;
}
You need break condition in the for loop. You are just invoking it, handle the returned status.
var ActionAttributes = function(data) {
var status = true;
var attrKey = data.AttributeKey();
//Condition to exit
if (attrKey == '' || attrKey == null) {
status = false;
return false;
}
for (var i = 0; i < data.Children().length; i++) {
var childData = data.Children()[i];
//You need to break loop here
//Add appropriate condition here
if (ActionAttributes(childData) == false) {
return false;
}
}
return status;
}
well, that recursion is not very useful to begin with.
you call a recursion of ActionAttributes inside the loop, but never handle the returned status. So the first caller will always receive true unless the exit condition meets on the first object.
you shoul store the return from ActionAttributes into status, and then break out of the loop as soon as it's false.

Javascript Recursion returning undefined

I'm struggling in a recursive Javascript function to find a specific subdirectory. This is my code:
function navigateToParent() {
var parentFullPath = parentDirectory(); // gets the full Path String
if (parentFullPath != null) {
var parent = getDirectoryByName(parentFullPath, rootDirectory);
// set the parent directory object as the current one
currentDirectory(parent);
}
}
function getDirectoryByName(fullName, myDirectory) {
if (myDirectory.fullName == fullName) {
return myDirectory;
} else {
var subs = myDirectory.subDirectories;
for (i = 0; i < subs.length; i++) {
return getDirectoryByName(fullName,subs[i]);
}
}
}
Every directory object has the properties fullName(string),subDirectories(array of directories) and files(array of files). My aim is to get the correct directory object, where it's fullName is matching.
I know, that i have to break the for loop in some way, but i don't know how to do it exactly.
After overthinking the logic i came to this solution (seems to work):
function getDirectoryByName(fullName, myDirectory) {
if (myDirectory.fullName == fullName) {
return myDirectory;
} else {
var subs = myDirectory.subDirectories;
for (i = 0; i < subs.length; i++) {
var match = getDirectoryByName(fullName, subs[i]);
if (typeof match !== "undefined"){
return match;
}
}
}
}

Checking multiple variables' values to make sure they all match

How do I efficiently check to see if multiple variables' values all match? The following function should return true if they match and false if they don't:
function projectIsLocked (data) {
if (data.ArchiveSnapshotID === data.CurrentSnapshotID === data.LiveSnapshotID) {
return true;
}
return false;
}
I thought I could just use if (data.ArchiveSnapshotID === data.CurrentSnapshotID === data.LiveSnapshotID) but it doesn't seem to work.
Ideas for something simple?
If there are just 3 comparisons , then this should be enough.
function projectIsLocked (data) {
var archive = data.ArchiveSnapshotID;
var current = data.CurrentSnapshotID;
var live = data.LiveSnapshotID;
return (archive === current && current === live)
}
Why not push them all to an array. This way you can use as many.
function check_for_equal_array_elements(my_array){
if (my_array.length == 1 || my_array.length == 0) {
return true;
}
for (i=0;i<my_array.length;i++){
if (i > 0 && my_array[i] !== my_array[i-1]) {
return false;
}
}
return true;
}
//Example:
var my_array = [];
my_array.push(5);
my_array.push(5);
// will alert "true"
alert("all elements equal? "+check_for_equal_array_elements(my_array));
my_array.push(6);
// will alert "false"
alert("all elements equal? "+check_for_equal_array_elements(my_array));
The problem here is, that a part of the logical expression is evaluated and then compared, so data.ArchiveSnapshotID === data.CurrentSnapshotID evaluated to "true" and data.LiveSnapshotID is checked against true, which you can see here (LiveSnapshotID was changed to boolean true):
function projectIsLocked (data) {
if (data.ArchiveSnapshotID === data.CurrentSnapshotID === data.LiveSnapshotID) {
return true;
}
return false;
}
var data = { ArchiveSnapshotID: "foo", CurrentSnapshotID: "foo", LiveSnapshotID: true };
alert(projectIsLocked (data));
You might want to use something like this, which is quite extensible for even more properties.
function projectIsLocked (data) {
var props = ["ArchiveSnapshotID", "CurrentSnapshotID", "LiveSnapshotID"];
for (var i = 1; i < props.length; i++)
{
if (data[props[i]] !== data[props[i - 1]])
return false;
}
return true;
}

Why am I getting an empty alert box?

I have js function onsubmit forms
var bCancel = false;
var errors = new Array();
function validateNewsForm(form) {
if (bCancel) {
return true;
} else {
errors = [];
var statusArray = new Array();
statusArray.push(validateRequired(form));
statusArray.push(validateMaxLength(form));
statusArray.push(validateDate(form));
for (status in statusArray) {
if (!status) {
alert(errors.join('\n'));
return false;
}
}
return true;
}
}
validateSmth() functions work fine. But when I input correct data I can't save because get empty alert. I have just one alert message and now that all validate functions gives true( in case correct data)
Why can I get empty alert?
for (status in statusArray) {
if (!status) {
A for in loop gives you keys. For an array these are indices. So you're effectively doing !0, !1, etc, and !0 evaluates to true.
You want a normal for loop:
for(var i = 0; i < statusArray.length; i++) {
if (!statusArray[i]) {
Also, you're using [] and new Array() together. It's best to just use [] everywhere.
because for status = 0 !status will be true.
Modified code:
for (var status = 0; status < statusArray.length; status ++) {
if (!statusArray[status] ) {
alert(errors.join('\n'));
return false;
}
}

Categories

Resources