I have this code:
// Required fields is an array of objects
required_fields.each(function() {
// Check each field: If it has no value, do nothing.
if( !$(this).val() ) {
return false;
}
// If all the fields are there, do something.
else {
alert('Doing something.');
}
});
I'm sure you can see the problem. Having the alert in the .each() function causes the alert to trigger for every item in the array. But what I want is to only trigger the event if ALL of the array items have a value—that is, if none return false.
What is the correct way to trigger something only if all the array items pass?
Just implement a little counter for each value.
var valueCount = 0;
required_fields.each(function () {
if (!$(this).val()) {
return false;
} else {
valueCount++; // increment to say has value
}
});
if (valueCount == required_feilds.length) {
alert('Doing something.');
}
You can use Array.prototype.every which will short circuit when a falsy value is returned:
var isTrue = [].every.call(required_fields, function(el) {
return $(el).val();
});
if (isTrue) {
console.log('Doing something');
}
I don't think you have an array but a jQuery object which is array like (got length and 0, 1, ... properties) So you can (ab)use the native Array prototype by setting the context with .call:
var every = Array.prototype.every;
every.call({ '0': 'a', '1': 'b', length: 2 }, console.log.bind(console));
// will output
// ['a', 0]
// ['b', 1]
Now that I think of it jQuery.fn.each will also short circuit if false is returned.
Two main options stand out:
1: Write a simple function that takes an array of jQuery objects and returns true if all items in the array have value
var allHaveValue = function(array){
for(var i = 0; i < array.length; i++){
if(!$(array[i]).val()){
return false;
}
}
return true;
};
// For your example
if(allHaveValue(required_fields)){
// Proceed
} else{
// Handle errors
}
The other alternative is doing the same thing but using the underscore.js function for [every][1]
[1]: http://underscorejs.org/#every which does the same thing. The call would look like:
var allHaveValue = _.every(required_fields, function(item){
return $(item).val();
});
if(allHaveValue)}{
// Proceed
} else{
// Handle errors
}
Related
Is it possible to create an array that will only allow objects of a certain to be stored in it? Is there a method that adds an element to the array I can override?
Yes you can, just override the push array of the array (let's say all you want to store are numbers than do the following:
var myArr = [];
myArr.push = function(){
for(var arg of arguments) {
if(arg.constructor == Number) Array.prototype.push.call(this, arg);
}
}
Simply change Number to whatever constructor you want to match. Also I would probably add and else statement or something, to throw an error if that's what you want.
UPDATE:
Using Object.observe (currently only available in chrome):
var myArr = [];
Array.observe(myArr, function(changes) {
for(var change of changes) {
if(change.type == "update") {
if(myArr[change.name].constructor !== Number) myArr.splice(change.name, 1);
} else if(change.type == 'splice') {
if(change.addedCount > 0) {
if(myArr[change.index].constructor !== Number) myArr.splice(change.index, 1);
}
}
}
});
Now in ES6 there are proxies which you should be able to do the following:
var myArr = new Proxy([], {
set(obj, prop, value) {
if(value.constructor !== Number) {
obj.splice(prop, 1);
}
//I belive thats it, there's probably more to it, yet because I don't use firefox or IE Technical preview I can't really tell you.
}
});
Not directly. But you can hide the array in a closure and only provide your custom API to access it:
var myArray = (function() {
var array = [];
return {
set: function(index, value) {
/* Check if value is allowed */
array[index] = value;
},
get: function(index) {
return array[index];
}
};
})();
Use it like
myArray.set(123, 'abc');
myArray.get(123); // 'abc' (assuming it was allowed)
//find value in array using function checkValue using underscoreJS _.each.
//return true, else false.
var helloArr = ['bonjour', 'hello', 'hola'];
var checkValue = function(arg) {
_.each(helloArr, function(helloArr, index) {
if (arg[index] === index) {
return true;
}
return false;
});
};
alert(checkValue("hola"));
The problem with your code is that, _.each will iterate through all the elements of the array and call the function you pass to it. You will not be able to come to a conclusion with that, since you are not getting any value returned from it (unless you maintain state outside _.each).
Note that the values returned from the function you pass to _.each will not be used anywhere and they will not affect the course of the program in any way.
But, instead, you can use _.some as an alternate, like this
var checkValue = function(arg) {
return _.some(helloArr, function(currentString) {
return arg === currentString;
});
};
But, a better solution would be, _.contains function for this purpose. You can use it like this
var checkValue = function(arg) {
return _.contains(helloArr, arg);
};
But, since you have only Strings in the Array, the best solution would be to use Array.prototype.indexOf, like this
var checkValue = function(arg) {
return helloArr.indexOf(arg) !== -1;
};
Try this:
var helloArr = ['bonjour', 'hello', 'hola'];
var checkValue = function(arr, val) {
_(arr).each(function(value) {
if (value == val)
{return console.log(true);}
else {return console.log(false);}
});
};
console.log(checkValue(helloArr,'hello'));
/* Output
false
true
false*/
I want return an empty object meanwhile the object equals to boolean false in my function.
Obviously,if I return {} like the code below,it equals to boolean true which cannot meet my request.
decodeAndParse: function (jsonStr) {
if (this.NaEptStr(jsonStr)) {
var result;
result = decodeURIComponent(jsonStr);
result = JSON.parse(result);
return result;
}
return false;
}
Is there any possible to solve this problem?
very thankful if anybody can help me solve this problem
Your code can be:
decodeAndParse: function (jsonStr) {
return this.NaEptStr(jsonStr)? JSON.parse(decodeURIComponent(jsonStr)) : {};
}
Then in the calling code you probably have something like:
var obj = foo.decodeAndParse(jsonStr);
if (obj) {
...
}
You could have a simple "emptyObj" test like:
function isEmptyObject(obj) {
return !!Object.keys(obj).length;
}
Then in the caller:
if (isEmptyObject(obj)) {
If you need to shim Object.keys, see MDN. Note that IE8 still has a significant user share (greater than 20% of desktop browsers according to netmarketshare) so don't ignore non–ES5 browsers.
make a function that counts keys in object
function isNotEmpty(obj){
var count = 0;
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
++count;
}
}
return count ? true : false;
}
and modify your if to
if (isNotEmpty(this.NaEptStr(jsonStr)))
But the simplest way to check if required field in object is present
if(this.naEpStr(jsonStr).myRequiredField)
When calling my function checkIss(), issFullArray.indexOf(issToCheck) always returns undefined. I've run a .length, output the contents of issFullArray, I can't figure out why it's not working- the array looks fine to me. As you can see below, I've tried explicitly setting issArray as an array and copying the array returned by my getIssList()
function updateIss() {
var issArray = [];
var currService = current.u_business_service;
var currIss = current.u_is_service;
issArray = getIssList(currService).slice(); //getIssList() returns an arry
if (checkIss(issArray, currIss) === false) {
//do stuff
}
}
function checkIss(issFullArray, issToCheck) {
if (issFullArray.indexOf(issToCheck) < 0) {
return false;
} else {
return true;
}
}
Easiest to just loop through the array and compare each value and return true if there is a match otherwise return false. Not much more code and works for all browsers.
function checkIss(issFullArray, issToCheck) {
for(i=0; i<issFullArray.length; i++) {
if(issFullArray[i]==issToCheck) {
return true;
}
}
return false;
}
From the node REPL thing,
> d = {}
{}
> d === {}
false
> d == {}
false
Given I have an empty dictionary, how do I make sure it is an empty dictionary ?
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
You could extend Object.prototype with this isEmpty method to check whether an object has no own properties:
Object.prototype.isEmpty = function() {
for (var prop in this) if (this.hasOwnProperty(prop)) return false;
return true;
};
How about using jQuery?
$.isEmptyObject(d)
Since it has no attributes, a for loop won't have anything to iterate over. To give credit where it's due, I found this suggestion here.
function isEmpty(ob){
for(var i in ob){ return false;}
return true;
}
isEmpty({a:1}) // false
isEmpty({}) // true
This is what jQuery uses, works just fine. Though this does require the jQuery script to use isEmptyObject.
isEmptyObject: function( obj ) {
for ( var name in obj ) {
return false;
}
return true;
}
//Example
var temp = {};
$.isEmptyObject(temp); // returns True
temp ['a'] = 'some data';
$.isEmptyObject(temp); // returns False
If including jQuery is not an option, simply create a separate pure javascript function.
function isEmptyObject( obj ) {
for ( var name in obj ) {
return false;
}
return true;
}
//Example
var temp = {};
isEmptyObject(temp); // returns True
temp ['b'] = 'some data';
isEmptyObject(temp); // returns False
I'm far from a JavaScript scholar, but does the following work?
if (Object.getOwnPropertyNames(d).length == 0) {
// object is empty
}
It has the advantage of being a one line pure function call.
var SomeDictionary = {};
if(jQuery.isEmptyObject(SomeDictionary))
// Write some code for dictionary is empty condition
else
// Write some code for dictionary not empty condition
This Works fine.
If performance isn't a consideration, this is a simple method that's easy to remember:
JSON.stringify(obj) === '{}'
Obviously you don't want to be stringifying large objects in a loop, though.
You'd have to check that it was of type 'object' like so:
(typeof(d) === 'object')
And then implement a short 'size' function to check it's empty, as mentioned here.
If you try this on Node.js use this snippet, based on this code here
Object.defineProperty(Object.prototype, "isEmpty", {
enumerable: false,
value: function() {
for (var prop in this) if (this.hasOwnProperty(prop)) return false;
return true;
}
}
);