Changing match to allow null input in javascript - javascript

I have some inherited code which is causing problems in Safari.
The problem comes from a few lines in the code that do things like this:
if ( ... && $("#element1").val().match(/regex/) && ...)
The javascript itself is programmatically generated.
The problem is that sometimes that $("#element1").val() returns null and I can't easily put a typeof check before it, because it needs to treat null as empty string.
The easiest (and manageable) solution would be either to create a nullmatch function and call that instead or to override the .match function itself. The new function would then check for null first and (if it is null) pass empty string to match instead of null.
I am not sure how to do either, or which would be best.

It would be better to either replace, or add to it (e.g.
$("element1").val().nullmatch(/regex/) or
$("element1").val().nullToEmpty().match(/regex/)
That isn't really possible, because .nullmatch or .nullToEmpty would need to be a method on a possibly null value.
If you really want to write in this fashion, or it's easier for your backend to generate, then you could write a mini-plugin:
$.fn.valNullToEmpty = function() { return this.val() || ''; }
$("element1").valNullToEmpty().match(/regex/)

You can use the || operator:
if ( ... && ($("#element1").val() || "").match(/regex/) && ...)
Basically, foo || "" will return foo if it's truthy, or the empty string if foo is falsy (false, undefined, null, empty string, +0, -0 or NaN).

How about...
function nullString(str) {
if (str === null) {
return "";
else {
return str;
}
So your if statement could become
if ( ... && nullString($("#element1").val()).match(/regex/) && ...)

The jQuery docs for val() state that it returns null when the element is select and no options are selected.
So using valHooks may help
var originalSelectHook;
if ($.valHooks.select) {
originalSelectHook = $.valHooks.select.get;
}
$.valHooks.select = {
get: function(elem) {
var index = elem.selectedIndex;
if (index == -1 || elem.options[index].disabled) {
return "";
}
else {
return originalSelectHook(elem)
}
};
Code assumes that there is a existing hook for select

Related

What is Simpler Way to Write Code That Sums Up Length of Strings including nulls and undefineds in JavaScript

I want to add some defensive coding to the following check. I have 3 strings and I want to know if any of them have anything in them (for my purposes, null or undefined means they do not have anything in them).
if (twitterUrl.length + facebookUrl.length + linkedInUrl.length > 0) {
This works, but feels like very bulky. I use TypeScript and not sure if there is anything there that can help me with this.
if ((twitterUrl ? twitterUrl.length : 0) +
(facebookUrl ? facebookUrl.length : 0) +
(linkedInUrl ? linkedInUrl.length : 0) > 0) {
You can use the fact that empty strings are falsy¹. If you know they'll be strings or null or undefined and you don't need to worry about strings with just whitespace in them (" " is truthy¹), then:
if (twitterUrl || facebookUrl || linkedInUrl) {
If you need to worry about trimming, then a helper function is probably in order:
function present(s) {
return s && (typeof s !== "string" || s.trim());
}
and
if (present(twitterUrl) || present(facebookUrl) || present(linkedInUrl)) {
or
if ([twitterUrl, facebookUrl, linkedInUrl].some(present)) {
¹ falsy and truthy: When you use a value in a condition (like an if), JavaScript will implicitly coerce the value to a boolean. A value that coerces to false is falsy; one that coerces to true is truthy. The falsy values are "", null, undefined, 0, NaN, and of course, false. All other values (including " ") are truthy.
You could define a function as the following one:
function getLength(s){
if(typeof s !== "string") return 0;
return s.length;
}
and then use it like below:
if (getLength(twitterUrl) > 0 || getLenght(facebookUrr) > 0 || getLength(linkedInUrl){
// code
}
Essentially, getLength check if the value you pass when you call the function is a string and if so it returns its length. Otherwise, it returns 0. So in order to achieve that you want, (I want to know if any of them have anything in them), you have to check one by one the strings you have, if the first string has a length greater than zero, there isn't any need to continue the check for the other two strings. Otherwise you call the function on the second string and so on and so forth.
Try like this, normal if statement also works
const socialLinks = [twitterUrl, facebookUrl, linkedInUrl];
const hasSomething = socialLinks.some(social => social);
Here is falsy value like null, undefined, '' and etc., https://developer.mozilla.org/en-US/docs/Glossary/Falsy
if social are empty string('') or null or undefined then it's return false. We omitted return keyword because arrow function has implicit return behaviour.
This is a solution using some(), which checks whether at least one element in the array passes the test implemented by the provided function.
var twitterUrl, facebookUrl, linkedInUrl;
linkedInUrl = 'nonEmpty';
result = [twitterUrl, facebookUrl, linkedInUrl].some(arrVal => arrVal);
console.log(result);

How to check if a value is not null and not empty string in JS

Is there any check if a value is not null and not empty string in Javascript? I'm using the following one:
var data; //get its value from db
if(data != null && data != '') {
// do something
}
But I'm wondering if there is another better solution. Thanks.
If you truly want to confirm that a variable is not null and not an empty string specifically, you would write:
if(data !== null && data !== '') {
// do something
}
Notice that I changed your code to check for type equality (!==|===).
If, however you just want to make sure, that a code will run only for "reasonable" values, then you can, as others have stated already, write:
if (data) {
// do something
}
Since, in javascript, both null values, and empty strings, equals to false (i.e. null == false).
The difference between those 2 parts of code is that, for the first one, every value that is not specifically null or an empty string, will enter the if. But, on the second one, every true-ish value will enter the if: false, 0, null, undefined and empty strings, would not.
Instead of using
if(data !== null && data !== '' && data!==undefined) {
// do something
}
You can use below simple code
if(Boolean(value)){
// do something
}
Values that are intuitively “empty”, like 0, an empty string, null, undefined, and NaN, become false
Other values become true
Both null and an empty string are falsy values in JS. Therefore,
if (data) { ... }
is completely sufficient.
A note on the side though: I would avoid having a variable in my code that could manifest in different types. If the data will eventually be a string, then I would initially define my variable with an empty string, so you can do this:
if (data !== '') { ... }
without the null (or any weird stuff like data = "0") getting in the way.
if (data?.trim().length > 0) {
//use data
}
the ?. optional chaining operator will short-circuit and return undefined if data is nullish (null or undefined) which will evaluate to false in the if expression.
I often test for truthy value and also for empty spaces in the string:
if(!(!data || data.trim().length === 0)) {
// do something here
}
If you have a string consisting of one or more empty spaces it will evaluate to true.
Simple solution to check if string is undefined or null or "":-
const value = null;
if(!value) {
console.log('value is either null, undefined or empty string');
}
Both null and empty could be validated as follows:
<script>
function getName(){
var myname = document.getElementById("Name").value;
if(myname != '' && myname != null){
alert("My name is "+myname);
}else{
alert("Please Enter Your Name");
}
}
try it----------
function myFun(){
var inputVal=document.getElementById("inputId").value;
if(inputVal){
document.getElementById("result").innerHTML="<span style='color:green'>The value is "+inputVal+'</span>';
}
else{
document.getElementById("result").innerHTML="<span style='color:red'>Something error happen! the input May be empty.</span>";
}
}
<input type="text" id="inputId">
<input type="button" onclick="myFun()" value="View Result">
<h1 id="result"></h1>
I got so fed up with checking for null and empty strings specifically, that I now usually just write and call a small function to do it for me.
/**
* Test if the given value equals null or the empty string.
*
* #param {string} value
**/
const isEmpty = (value) => value === null || value === '';
// Test:
isEmpty(''); // true
isEmpty(null); // true
isEmpty(1); // false
isEmpty(0); // false
isEmpty(undefined); // false
When we code empty in essence could mean any one of the following given the circumstances;
0 as in number value
0.0 as in float value
'0' as in string value
'0.0' as in string value
null as in Null value, as per chance it could also capture undefined or it may not
undefined as in undefined value
false as in false truthy value, as per chance 0 also as truthy but what if we want to capture false as it is
'' empty sting value with no white space or tab
' ' string with white space or tab only
In real life situation as OP stated we may wish to test them all or at times we may only wish to test for limited set of conditions.
Generally if(!a){return true;} serves its purpose most of the time however it will not cover wider set of conditions.
Another hack that has made its round is return (!value || value == undefined || value == "" || value.length == 0);
But what if we need control on whole process?
There is no simple whiplash solution in native core JavaScript it has to be adopted. Considering we drop support for legacy IE11 (to be honest even windows has so should we) below solution born out of frustration works in all modern browsers;
function empty (a,b=[])
{if(!Array.isArray(b)) return;
var conditions=[null,'0','0.0',false,undefined,''].filter(x => !b.includes(x));
if(conditions.includes(a)|| (typeof a === 'string' && conditions.includes(a.toString().trim())))
{return true;};
return false;};`
Logic behind the solution is function has two parameters a and b, a is value we need to check, b is a array with set conditions we need to exclude from predefined conditions as listed above. Default value of b is set to an empty array [].
First run of function is to check if b is an array or not, if not then early exit the function.
next step is to compute array difference from [null,'0','0.0',false,undefined,''] and from array b. if b is an empty array predefined conditions will stand else it will remove matching values.
conditions = [predefined set] - [to be excluded set]
filter function does exactly that make use of it.
Now that we have conditions in array set all we need to do is check if value is in conditions array.
includes function does exactly that no need to write nasty loops of your own let JS engine do the heavy lifting.
Gotcha
if we are to convert a into string for comparison then 0 and 0.0 would run fine however Null and Undefined would through error blocking whole script. We need edge case solution. Below simple || covers the edge case if first condition is not satisfied. Running another early check through include makes early exit if not met.
if(conditions.includes(a)|| (['string', 'number'].includes(typeof a) && conditions.includes(a.toString().trim())))
trim() function will cover for wider white spaces and tabs only value and will only come into play in edge case scenario.
Play ground
function empty (a,b=[]){
if(!Array.isArray(b)) return;
conditions=[null,'0','0.0',false,undefined,''].filter(x => !b.includes(x));
if(conditions.includes(a)||
(['string', 'number'].includes(typeof a) && conditions.includes(a.toString().trim()))){
return true;
}
return false;
}
console.log('1 '+empty());
console.log('2 '+empty(''));
console.log('3 '+empty(' '));
console.log('4 '+empty(0));
console.log('5 '+empty('0'));
console.log('6 '+empty(0.0));
console.log('7 '+empty('0.0'));
console.log('8 '+empty(false));
console.log('9 '+empty(null));
console.log('10 '+empty(null,[null]));
console.log('11 dont check 0 as number '+empty(0,['0']));
console.log('12 dont check 0 as string '+empty('0',['0']));
console.log('13 as number for false as value'+empty(false,[false]));
Lets make it complex - what if our value to compare is array its self and can be as deeply nested it can be. what if we are to check if any value in array is empty, it can be an edge business case.
function empty (a,b=[]){
if(!Array.isArray(b)) return;
conditions=[null,'0','0.0',false,undefined,''].filter(x => !b.includes(x));
if(Array.isArray(a) && a.length > 0){
for (i = 0; i < a.length; i++) { if (empty(a[i],b))return true;}
}
if(conditions.includes(a)||
(['string', 'number'].includes(typeof a) && conditions.includes(a.toString().trim()))){
return true;
}
return false;
}
console.log('checking for all values '+empty([1,[0]]));
console.log('excluding for 0 from condition '+empty([1,[0]], ['0']));
it simple and wider use case function that I have adopted in my framework;
Gives control over as to what exactly is the definition of empty in a given situation
Gives control over to redefine conditions of empty
Can compare for almost for every thing from string, number, float, truthy, null, undefined and deep arrays
Solution is drawn keeping in mind the resuability and flexibility. All other answers are suited in case if simple one or two cases are to be dealt with. However, there is always a case when definition of empty changes while coding above snippets make work flawlessly in that case.
function validateAttrs(arg1, arg2, arg3,arg4){
var args = Object.values(arguments);
return (args.filter(x=> x===null || !x)).length<=0
}
console.log(validateAttrs('1',2, 3, 4));
console.log(validateAttrs('1',2, 3, null));
console.log(validateAttrs('1',undefined, 3, 4));
console.log(validateAttrs('1',2, '', 4));
console.log(validateAttrs('1',2, 3, null));

javascript hash values validation

I'm trying to give the same behaviour to 4 values in my hash array.
For example:
var array = {};
if (array[key].config.tmp == undefined) {
array[key].config.tmp = {}
}
if(array[key].config.tmp.tp1){
}
if(array[key].config.tmp.tp2){
}
if(array[key].config.tmp.tp3){
}
if(array[key].config.tmp.tp4){
}
Since tp1, tp2, tp3 and tp4 will have the same behaviour. I would like to simplify the validation.
Something like:
array[key].config.tmp.[tp1,tp2,tp3,tp4] is possible? Already tried. but it was
tp1,tp2,tp3 and tp4 may not exist(undefined). (tp1 and tp2 only sometimes).
Any advice so I won't duplicate code?
Thanks in advance
You could also use a filter on the array keys:
if ( ( array[key].config.tmp || {} ).keys().filter(
function(k) { return /^tp[1234]/.test( k ) }
).length ) )
use a short-circuit operator like ||. for instance, if you are checking for the existence of multiple properties, accessing a property which doesn't exist is falsy.
var c = a[key].config.tmp.a || a[key].config.tmp.b || .... || //default
In this example, c will hold the value of the first of these to evaluate to true. You could also include a "Default" value at the end if they all return false. Keep in mind that accessing a property of a property that doesn't exist is a type error however, so you must be sure that at least config.tmp exists. So you can replace your code with
if (a[key].config.tmp.a || a[key].config.tmp.b || ....) {
}

Is this the best way to check if a variable is defined, not null and equal to "" or anything else

I need to set a value if my variable is defined, not null and equal to "" or anything else.
I am using the following:
if (typeof abc != 'undefined') {
if (abc != null) {
// Here the variable abc must be defined
// not null
// equal to "" or anything else such as a longer string or number
}
}
Can someone tell me if this is best way for me to implement the check that I need.
var abc2 = abc.toString();
if (abc2.length > 0)
If length > 0 so, it's setted
Javascript validates any of those cases as booleans, so:
if ( abc ) {
....
}
checks all of those cases.

How to check if a value passed to a JavaScript function is defined or its length is >=0?

I have the following javascript code:
function changeButtonState(targetSelector, action, iconClass) {
var $target = $(targetSelector);
var $targetSpan = $(targetSelector + ' span');
$targetSpan.removeClass('sprite-blank').addClass(iconClass);
}
How can I make it so that the $targetSpan.removeClass(..).addClass only work if the iconClass has a value when the function is called. I guess what I am confused about is do I check if it is defined or do I check if it has a length of 0 or more?
Just use an if statement:
if (iconClass){}
Or, typeof:
if (typeof iconClass != 'undefined') {}
if (typeof(iconClass)=='undefined') {
// nothing was passed
}
LIVE DEMO
if ( 'undefined' != typeof iconClass ) { /**/ }
Your use case you must assume that iconClass is a string. In which case I would suggest the first if condition. The second one is probably too restrictive, it usually is only used if the person calling the function does not actually pass a 3rd parameter, or passes undefined. But if the caller passes null or empty string, the first if condition will catch those conditions as well. It is the easiest one to write and it is very common in Javascript to simply check if (variable) { } because it will catch a lot more and is very easy to read and write.
if (iconClass) {
// Executes if iconClass is not null, not undefined, not 0, and not empty string
}
if (typeof iconClass != 'undefined') {
// WILL execute if iconClass is null, 0, empty string
// Only will not execute if iconClass is undefined!
}
Presumably, iconClass should be a string (a class name), so you should test to see if it's a string:
if (typeof iconClass == 'string')
or you could use a regular expression to test that it's a valid class name at the same time:
if (/^[a-z][a-z0-9]*$/i.test(iconClass))
The regular expression likely needs more characters to test for (hyphen at least), I'll leave that to you. The accepted answer to What characters are valid in CSS class names? may help.
if(iconClass.length > 0){
$targetSpan.removeClass('sprite-blank').addClass(iconClass);
}

Categories

Resources