I have a function expression like this :
var inputChecker = function(field) {
return function() {
if(field === '' || field === 'undefined' || field === null) {
return false;
}
return true;
}
}
that I want to use in several different function expressions :
(function($) {
if(inputChecker(x)) {}
})(jQuery);
(function($) {
})(jQuery);
But the problem is inputChecker is not visible in these function expressions when it's declared out of their bodies ? I don't understand why? Isn't inputChecker supposed to be global ?
Dystroy's answer is definitely simpler. But if you want it your way...
The return value of the inputChecker is a function, not boolean. If you want to call the returned function, use () expression:
var fn = inputChecker(x); // gets the function
fn(); // calls the returned function
or shorter
inputChecker(x)();
In your code
(function($) {
if(inputChecker(x)()) {
// custom code here if x is defined
}
})(jQuery);
Note: if you want to check if variable is not undefined, strip the apostrophes - undefined is constant, not string
if(field===undefined)
What you wrote is a function factory. It doesn't return a boolean but a function able to check a property.
This kind of functions is sometimes useful but :
you're here, in the returned function, checking the value of the property received by the factory. As this value can't change (it's embedded in the closure), the produced function holds no more information than just true or false. So it's useless.
you're calling inputChecker(x) as if it was a boolean instead of a function.
So what you probably want is simply
var checkInput = function(field) {
if(field === '' || field === 'undefined' || field === null){
return false;
}
return true;
}
But if you really want to generate different checking functions, dependent on another value, you could use the function factory pattern like this:
var x = true;
var checkInput = (function (x) {
if (x === true) {
return function(field) {
if(field === '' || field === 'undefined' || field === null){
return false;
}
return true;
}
} else {
return function(field) {
//evaluate field differently
}
}
}(x));
Now, dependig on what x is, one or another function will be assigned to checkInput.
Related
Is it possible to have object extensions in JavaScript? For example
Extensions.js
function any.isNullOrEmpty() {
if (this == null || this == "") {
return true
}
return false
}
app.js
var x = ""
console.log(x.isNullOrEmpty()) //should log true
is this possible? How do I do it?
You could add a method to the Object prototype, and use the valueOf method to get the value of the string:
...but, because null is a primitive that cannot have a method, the only way I can think of to get the target to be null would be to use call, apply or bind.
But you would never do this in production code, because modifying the prototype of built-in objects is discouraged.
'use strict' // important for the use of `call` and `null`
Object.prototype.isNullOrEmpty = function() { return this === null || this.valueOf() === '' }
const s = ''
console.log(s.isNullOrEmpty())
const t = null
console.log(Object.prototype.isNullOrEmpty.call(t))
You could use Object.prototype to extend this type of functionality in JavaScript.
Object.prototype.isNullOrEmpty = function() {
if (this == null || this == "") {
return true
}
return false
}
var x = "";
x.isNullOrEmpty(); // returns true
you need to add your custom method into prop type of object or array or everything u want to use your method on it.
but in your case you need to this like code below:
Object.prototype.isNullOrEmpty = function(){
if (this === null || this == "") {
return true
}
return false
}
let a = {a:'10'}
console.log(a.isNullOrEmpty())
function validateValue(value){
function isNullEmpty(){
return (value === void (0) || value == null)
}
return { isNullOrEmpty }
}
}
I'm programming a poker program in JavaScript. I have a Hand class that has the properties "cards", "value" and "valueCards". The value property is an integer that corresponds to a hand type, and the valueCards is the array of five cards that also corresponds to the hand type. For example, if my original seven cards(contained in the cards property) contains a flush, this.value will flip to 6, and this.valueCards will equal only the five cards that equal the highest flush.
I have one method for each hand type, and ALL of them change the value and valueCards if that hand type is detected. I have an accessor method for value called getValue, so when I went to make a method to run all the tests on a hand and keep the highest one, it came out looking like this:
POKER.Hand.prototype.getTrueValue = function () {
this.testStraightFlush();
if(this.value == POKER.HAND_TYPE.STRAIGHT_FLUSH){ return; }
this.testQuads();
if(this.value == POKER.HAND_TYPE.QUADS){ return; }
this.testFullHouse();
if(this.value == POKER.HAND_TYPE.FULL_HOUSE){ return; }
this.testFlush();
if(this.value == POKER.HAND_TYPE.FLUSH){ return; }
this.testStraight();
if(this.value == POKER.HAND_TYPE.STRAIGHT){ return; }
this.testTrips();
if(this.value == POKER.HAND_TYPE.TRIPS){ return; }
this.testTwoPair();
if(this.value == POKER.HAND_TYPE.TWO_PAIR){ return; }
this.testPair();
if(this.value == POKER.HAND_TYPE.PAIR){ return; }
this.getHighCards();
};
I mean, the method works fine. It just bothers me, like maybe I should be doing it a different way. Does this go against convention?
If you change your this.test* functions to return true if the "hand" is found, or return false if not - then you could do something as ugly, yet somehow satisfying, as
POKER.Hand.prototype.getTrueValue = function () {
this.testStraightFlush() ||
this.testQuads() ||
this.testFullHouse() ||
this.testFlush() ||
this.testStraight() ||
this.testTrips() ||
this.testTwoPair() ||
this.testPair() ||
this.getHighCards();
};
or
change your this.test* functions to check only if this.found is false, and set this.found = true if a hand is found, so you'd simply
POKER.Hand.prototype.getTrueValue = function () {
this.found = false;
this.testStraightFlush();
this.testQuads();
this.testFullHouse();
this.testFlush();
this.testStraight();
this.testTrips();
this.testTwoPair();
this.testPair();
this.getHighCards();
};
Not an answer but I would redesign your functions :
Each method should return the prop itself :
function testFlush ()
{
if (...) return POKER.HAND_TYPE.FLUSH;
return null;
}
function testStraightFlush()
{
if (...) return POKER.HAND_TYPE.StraightFlush;
return null;
}
This way , you'll be able to get both value and check for truness.
POKER.Hand.prototype.getValue= function ()
{
return this.testFlush () || testStraightFlush()
};
Just for the fun of it, you could redesign the tests like this:
POKER.Hand.prototype.getTrueValue = function () {
var tests = [
[ "testStraightFlush", POKER.HAND_TYPE.STRAIGHT_FLUSH ],
[ "testQuads" , POKER.HAND_TYPE.QUADS ],
[ "testFullHouse" , POKER.HAND_TYPE.FULL_HOUSE ],
... etc...
];
for (var test in tests) {
var fun = this[tests[test][0]];
var val = tests[test][1];
fun();
if (this.value == val) {
return;
}
}
this.getHighCards();
};
Or the functions might simply return a boolean, so you could have a simpler tests array
var tests = [
"testStraightFlush",
"testQuads" ,
"testFullHouse" ,
... etc...
];
I want to set different value to self.selectedTitleId() in knockoutjs when self.selectedQueryId changes, so i have added a subscribe to selectedQueryId.
I have another computed variable self.text which format the self.selectedTitleId with other variables.
My problem is , when i change the selectedQueryId value from UI, computed function gets called first, followed by subscribe call. Because of this, the text that i am trying to display always holds the previous selection value.
I want to hold the self.text computed function execution until selectedTitleId.subscribe function is completed so that self.selectedTitleId has current value.
Can someone help me? Thanks for your time!
Below is the html component which is used to bing selectedTitleId value with UI. backend js always shows the 'backendName' as value, even though i tried to set a different value using self.selectedTitleId("newValue").
html:
var sformat = (function() {
var pattern = /\{\{|\}\}|\{(\d+)\}/g;
return function () {
var parameters = arguments;
if(parameters[0]) {
console.log(parameters[0])
return parameters[0].replace(pattern, function (match, group) {
var value;
if (match === "{{")
return "{";
if (match === "}}")
return "}";
value = parameters[parseInt(group, 10) + 1];
return value ? value.toString() : "";
});
}
};
});
function test() {
return sformat.apply(this, arguments);
}
self.selectedTitleId = ko.observable('');
self.text = ko.computed(function () {
console.log("inside text function")
if (self.selectedTitleId && self.selectedQueryId()) {
console.log(self.selectedTitleId)
self.displayField = test(self.selectedTitleId, self.selectedQueryId(),self.queryValue());
}else if(self.selectedTitleId && self.selectedQueryId() && self.queryGreaterValue() && self.queryLesserValue()){
self.displayField = test(self.selectedTitleId, self.selectedQueryId(),self.queryValue(),self.queryGreaterValue(),self.queryLesserValue());
}
return self.displayField;
});
self.selectedQueryId.subscribe(function (newValue) {
$.getJSON("json/queries.json", function (allData) {
var mappedData = $.map(allData, function (item) {
if(item.DisplayName == "Price"){
if(newValue == "range") {
self.selectedTitleId(item.RangeBackEndFieldName);
console.log("range");
console.log(item.RangeBackEndFieldName); //Prints new string
console.log(self.selectedTitleId()); //Print old value-
}else if(newValue == "$gt:" || newValue == "$lt:"){
self.selectedTitleId(item.BackendFieldName);
});
}
}
});
});
});
Unless there is something else you are not telling us, it doesn't make sense for selectedTitleId to be a ko.computed. Just use a regular observable:
self.selectedTitleId = ko.observable();
self.selectedQueryId.subscribe(function (newValue) {
$.getJSON("json/queries.json", function (allData) {
var mappedData = $.map(allData, function (item) {
if(item.DisplayName == "Price"){
if(newValue == "range") {
self.selectedTitleId(item.RangeBackEndFieldName);
});
}else if(newValue == "$gt:" || newValue == "$lt:"){
self.selectedTitleId(item.BackendFieldName);
});
}
}
});
});
});
Now when selectedTitleId is changed in your callback, it should trigger text to re-evaluate.
The problem with your original wasn't that it was updating text first, it was that it wasn't re-evaluating when you changed selectedTitleId. See here:
if (self.selectedTitleId() && self.selectedQueryId()) {
This means your computed property is dependent on both selectedTitleId and selectedQueryId, updating either will cause the function to run again. But in your original code, you completely replaced self.selectedTitleId with an entirely new function, but your computed is still dependent on the old one (which is unchanged).
I'm asking myself if it's possible to call a function in js, while having additional subfunction inside it
fn(s);
fn.subfn(s);
for example to make utils like this
var s = "123";
string(s) // true
string.blank(s) // false
I think it's possible like this:
function string(s) {
if(s) return typeof(s) === "string";
return {
blank: function(s) {
return s.trim().length === 0;
}
}
}
but every time i call string(s) i'm redefining blank fn, with possible poor performances and poor code, or i'm wrong?
Thanks.
Functions are just objects, so yes, you can just add properties to them:
function string(s) {
return typeof(s) === "string";
}
string.blank = function(s) {
return s.trim().length === 0;
}
This would allow you to make the calls
string(s);
string.blank(s);
just as shown in your example.
Comments to your code:
The function you defined returns an object when you call string, so you would require to call the function as
string().blank(s);
which would be different form the example you showed at the beginning.
You can create a Thing() class and instantiate "thing" objects to prevent redefining functions. (Thing() instead of string() to prevent any sort of collision.)
function Thing(s) {
return {
isString: function() {
return typeof(s) === "string";
},
isBlank: function() {
return s.trim().length === 0;
}
};
}
var t = new Thing("123");
t.isString() // true
t.isBlank() // false
http://jsfiddle.net/KKrsa/
You could try something like this (untested):
function string(s) {
if(s) return typeof(s) === "string";
}
string.blank = function(s) {
return s.trim().length === 0;
}
You might run into issues using "string" for the name of your function, though, because it may clash with the existing String object.
I saw many places similar question but couldn't fix it.
Here's my function:
function validate_form(){
$('#form_data input[type="text"]').each(function(){
value = $(this).val().trim();
if(value != '' && value != null && value != 0 ){
return true;
}
});
return false;
}
Its not exiting on return true;. I have also tried e.preventDefault() but no use.
return will return from the function it is in. In your code, that is the anonymous function you pass to each. See the documentation for each:
You can stop the loop from within the callback function by returning false.
You are returning true, not false so you aren't stopping the loop. Change true to false on line 5 of the function.
function validate_form(){
$texts=$('#form_data input[type="text"]'); //cache the object
var len = $texts.length;
var validItems=0;
$texts.each(function(){
value = $(this).val().trim();
if(value === ''){ // value of a text input cannot be null
// or zero unless you've changed in with JS
return false;
}
validItems++;
});
return len===validItems;
}
The function doesn't exactly show what item is invalid, just returns false if any of the items is invalid.
You have to let the .each() finish before you return from the main function body. You can keep a counter of valid entries you have come across and let the return value depend on that:
function validate_form()
{
var items = $('#form_data input[type="text"]'),
count = items.length,
valid = 0;
items.each(function() {
value = $(this).val().trim();
if (value != '' && value != null && value != 0 ) {
++valid;
}
});
return valid !== count;
}
Btw, I've changed the return value to false if there's at least one invalid entry; assuming you're using this as onsubmit="return validate_form()".