Why am I getting an empty alert box? - javascript

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;
}
}

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.

Execute the else statement if none of the items are found

I have this for loop, and I would like to execute the else in the for loop only if none of the if conditions are met. The for loop runs until every item in the database has been checked. If none of the items in the database matches the user input then I want to run the else.
Right now, it runs the else right after the first try which means if the item matches is in the last row, it will just throw it in the error page since it stops the evaluation at the first iteration.
for(var i=0; i< rows.length; i++) {
if (rows[i].hashtag == userEnteredHashtag) {
// Display the choose Box page
res.render('chooseBox', {});
}
else {
// Display the invalid hashtag page
res.render('invalidHashtag', {});
}
}
Just move the else portion outside of the loop and execute it based on a flag
var wasFound = false;
for (var i = 0; i < rows.length; i++) {
if (rows[i].hashtag == userEnteredHashtag) {
// ...
wasFound = true; // set the flag here
}
}
if (!wasFound) {
res.render('invalidHashtag', {});
}
So add a check outside.
var hasMatch = false;
for (var i = 0; i < rows.length; i++) {
if (rows[i].hashtag == userEnteredHashtag) {
// Display the choose Box page
res.render('chooseBox', {});
hasMatch = true;
}
}
if (!hasMatch) {
// Display the invalid hashtag page
res.render('invalidHashtag', {});
}
Create a variable to track whether your condition has been met:
var isValid = true;
for(var i=0; i< rows.length; i++) {
if (rows[i].hashtag != userEnteredHashtag) {
isValid = false
}
}
isValid ? res.render('chooseBox') : res.render('invalidHashtag')
Another way to do it is to use filter and forEach.
var rows = [{hashtag: '#a'}, {hashtag: 'b'}, {hashtag: 'c'}];
var userEnteredHashTag = '#a';
var matchingRows = rows.filter(row => row.hashtag === userEnteredHashTag);
if (matchingRows.length) {
matchingRows.forEach(row => console.log(row));
} else {
console.log('invalid');
}

Multiple Email Validation using regex. Loop terminates after first validation

I think I am very close here.
I'm trying to iterate through an array and at each iteration, check whether the value is a valid email address.
The problem is, the loop terminates once it hits either a false or a true. How do I iterate through an array without terminating the loop?
validateForm: function() {
var emails = $('#email-addresses').val(),
emailArray = emails.split(',');
for (var i = 0; i < emailArray.length; i++) {
if( ! this.validateEmail(emailArray[i].trim())) {
return false;
}
return true;
};
},
validateEmail: function(email) {
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
It depends on what you want to do here. If you want to hold a result for every check then look at lincb answer. If you want just a true / false about whether all emails were valid then do:
validateForm: function() {
var emails = $('#email-addresses').val(),
emailArray = emails.split(',');
var isValid = true;
for (var i = 0; i < emailArray.length && isValid == true; i++) {
if( ! this.validateEmail(emailArray[i].trim())) {
isValid = false;
}
};
return isValid;
},
In Javascript, return will end the function regardless of any loops. Here is a possible fix:
validateForm: function() {
var emails = $('#email-addresses').val(),
emailArray = emails.split(',');
var returns = new Array();
for (var i = 0; i < emailArray.length; i++) {
if( ! this.validateEmail(emailArray[i].trim())) {
returns[i] = false;
}
returns[i] = true;
}
return returns;
},

Javascript: What is wrong with this conditional?

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

Categories

Resources