Javascript Empty String vs (null and undefined) [duplicate] - javascript

This question already has answers here:
How can I check for "undefined" in JavaScript? [duplicate]
(16 answers)
Closed 6 years ago.
I have a object
var data = {1:undefined,2:null,3:10,4:""}
I want to replace all the undefined and null values by 0. I am using the following code to do that:
for (var index in data) {
if (!data[index]) {
data[index] = 0;
}
}
Result I am expecting is : {1:0,2:0,3:10:4:""}
But Result is : {1:0,2:0,3:10:4:0} because it is considering empty string as null. Is it known behavior ?
I can check it by using
(if(data[index] == undefined || data[index] == null))
But I wanted to know the behavior of the above solution.

You can add typeof data[index] != 'string'
var data = {1:undefined,2:null,3:10,4:""}
for (var index in data) {
if (!data[index] && typeof data[index] != 'string') {
data[index] = 0;
}
}
console.log(data)

This is because a string of length 0 is "falsy", which means that it, if evaluated as a boolean, will translate to false. Read more on "falsy" over here. You can fix your code in the following way:
for (var index in data) {
if (typeof data[index] == "undefined" || data[index] == null) {
data[index] = 0;
}
}

Try:
if ((typeof <your variable> == "undefined") ||
( <your variable> == "" ) ) {
<your variable> = 0 ;
}
By the way, Are you using "1", "2" indices?

Related

If conditional giving true although it's supposed to be false [duplicate]

This question already has answers here:
Check variable equality against a list of values
(16 answers)
What is the difference between the `=` and `==` operators and what is `===`? (Single, double, and triple equals)
(5 answers)
What is an off-by-one error and how do I fix it?
(6 answers)
Closed 4 months ago.
I'm having problem with the conditional always returning true. I'm not sure if it's the value it's seeing as truthy in general but it's messing with me.
Problem: Check to see if a string has the same amount of 'x's and 'o's. The method must return a boolean and be case insensitive. The string can contain any char.
Examples input/output:
XO("ooxx") => true
XO("xooxx") => false
XO("ooxXm") => true
XO("zpzpzpp") => true // when no 'x' and 'o' is present should return true
XO("zzoo") => false
function XO(str) {
let on = 0
let xn = 0
let result = ""
for (let i = 0; i <=str.length; i++) {
if (str[i] = "x" || "X"){
xn++
} if (str[i] = "o" || "O") {
on++
};
if (xn == on || xn && on == 0){
result = true
}else if (xn !== on) {
result = false
}
return result
}
}
Seems the conditional is always returning true. Not sure if it's because the types are true (which is why I kept it strict).
You have 3 mistakes in your XO function.
You have used assignment operator : = instead of equality
comparison operator : ==.
You are checking condition str[i] == "x" || "X". The correct way to write this is : str[i] == "x" || str[i] == "X".
You are checking xn==on inside the for loop. You should check that once your for loop is over.
Here is the correct code -
function XO(str) {
let on = 0
let xn = 0
for (let i = 0; i < str.length; i++) {
if (str[i] == "x" || str[i] == "X") {
xn++
continue;
}
if (str[i] == "o" || str[i] == "O") {
on++
continue;
};
}
return xn==on;
}
You just use toLowerCase() and at the end return if on===xn
function XO(str) {
let on = 0;
let xn = 0;
for (let i = 0; i < str.length; i++) {
if (str[i].toLowerCase() === "x") {
xn++;
}
if (str[i].toLowerCase() === "o") {
on++;
};
}
return xn === on
}
console.log(XO("ooxx"))
console.log(XO("xooxx"))
console.log(XO("ooxXm"))
console.log(XO("zpzpzpp"))
console.log(XO("zzoo"))

How to check two conditions with && correctly

I want to loop through an array and check if each element is a number OR a string that could potentially turned into a number (e.g. "42"). If it can be "converted" then the element should be stored in a new array.
This is my code where I push all converted elements into a new array. Notice: I also want to count how many elements were "converted" from a string into a number and how many were not.
function numberConverter(arr) {
var converted = []
var counterConverted = 0
var counterNotConverted = 0
for (var c of arr) {
if (typeof c == "string" && Number(c) == "number") {
counterConverted++;
parseInt(c, 10);
converted.push(c)
} else {
counterNotConverted++
}
}
if (counterConverted == 0) {
return "no need for conversion"
} else {
return counterConverted + " were converted to numbers: " + converted + "; " + counterNotConverted + " couldn't be converted"
}
}
I know that my if condition
if(typeof c == "string" && Number(c) == "number")
is flawed logically, but I can't make up why.
Thanks for any hints and please explain it in beginner terms.
You can test if a string could be converted to a number like so:
val !== "" && Number.isNaN(Number(val)) === false
And the code could be written like so:
function numberConverter(arr) {
var converted = [];
var notconverted = [];
arr.forEach(function(val) {
if (typeof val === "number") {
converted.push(val);
} else if (typeof val === "string" && val !== "" && Number.isNaN(Number(val)) === false) {
converted.push(Number(val));
} else {
notconverted.push(val);
}
});
console.log("converted", converted);
console.log("not converted", notconverted);
}
numberConverter([0, "1", "", "123-foo", undefined, null, true, [], {}]);
The best solution is to use a functional approach to the code rather than an imperative one.
let arrayNumbers = ["Vadim", 99, {}, [], "100", "55AA", "AA55", Infinity, "false", true, null, -65.535, 2E1, "2E2"].filter( value => value !== null && value != Infinity && value !== '' && !isNaN(Number(value)) && !['boolean','array','object'].includes(typeof value)).map(value => +value);
console.log('Was Converted to Numbers:', arrayNumbers);
You need to check typeof string and isNaN in ESLint way (Number.isNaN(Number())).
function numberConverter(arr) {
const converted = [];
let counterConverted = 0;
for (let i = 0; i < arr.length; i += 1) {
const str = arr[i];
if (str && typeof str === 'string' && !Number.isNaN(Number(str))) {
const number = parseInt(str, 10);
converted.push(number);
counterConverted += 1;
}
}
const counterNotConverted = arr.length - converted.length;
if (counterConverted === 0) {
return 'No need for conversion.';
}
return `${counterConverted} were converted to numbers: ${converted.join(',')}; ${counterNotConverted} couldn't be converted`;
}
console.log(`'${numberConverter(['id', null, {}])}'`); // No need for conversion.
console.log(`'${numberConverter(['1', '-1', 'val'])}'`); // 2 were converted to numbers: [1,-1]; 1 couldn't be converted
console.log(`'${numberConverter(['1', '-1', '0', '1.5', 'val'])}'`); // 4 were converted to numbers: [1,-1,0,1]; 1 couldn't be converted

Error while accessing javascript array element inspite of having checks

I am doing following in my javascript code
if(
typeof player['stats'] != undefined &&
typeof player['stats']['guild'] != undefined &&
typeof player['stats']['guild']['master'] != undefined &&
typeof player['stats']['guild']['master']['since'] != undefined
)
However I get error:
Cannot read property 'since' of null
I have been stuck with this for a while. Can any javascript gurus help me please?
typeof returns string, so compare against "undefined"
if(
typeof player['stats'] != "undefined" &&
typeof player['stats']['guild'] != "undefined" &&
typeof player['stats']['guild']['master'] != "undefined" &&
player['stats']['guild']['master'] != null &&
typeof player['stats']['guild']['master']['since'] != "undefined"
)
Just check if the value is truthy:
if(
player['stats'] &&
player['stats']['guild'] &&
player['stats']['guild']['master'] &&
player['stats']['guild']['master']['since'] != undefined // only check the last one as it is probably not an object but another value such as 0 (depending on what your data looks like, if you have it as an object then just remove the != undefined check)
)
You could write a fairly simple object getter function which you pass the object and then a dot-delimited key to find a value like so:
function getObj(obj, key) {
return key.split(".").reduce((acc, cur) => {
if (acc !== undefined) {
return acc[cur];
}
return acc;
}, obj);
}
Then, you can grab the value that you want and see if it's undefined or not:
const player = {
stats: {
guild: {
master: {
since: '2004'
}
}
}
};
const since = getObj(player, 'stats.guild.master.since');
if (since) {
// do some code
}
This is a handy utility function you can use on any object and makes your if statement much prettier.
You can also avoid the multiple lookups with a temporary variable:
player = { stats: { guild: { master: null } } }
if ((temp = player.stats) &&
(temp = temp.guild) &&
(temp = temp.master) &&
(temp = temp.since) !== undefined)
console.log(true , temp)
else
console.log(false, temp)
player.stats.guild.master = { since: 'today' }
if ((temp = player.stats) &&
(temp = temp.guild) &&
(temp = temp.master) &&
(temp = temp.since) !== undefined)
console.log(true , temp)
else
console.log(false, temp)

'IsNullOrWhitespace' in JavaScript?

Is there a JavaScript equivalent to .NET's String.IsNullOrWhitespace so that I can check if a textbox on the client-side has any visible text in it?
I'd rather do this on the client-side first than post back the textbox value and rely only on server-side validation, even though I will do that as well.
For a succinct modern cross-browser implementation, just do:
function isNullOrWhitespace( input ) {
return !input || !input.trim();
}
Here's the jsFiddle. Notes below.
The currently accepted answer can be simplified to:
function isNullOrWhitespace( input ) {
return (typeof input === 'undefined' || input == null)
|| input.replace(/\s/g, '').length < 1;
}
And leveraging falsiness, even further to:
function isNullOrWhitespace( input ) {
return !input || input.replace(/\s/g, '').length < 1;
}
trim() is available in all recent browsers, so we can optionally drop the regex:
function isNullOrWhitespace( input ) {
return !input || input.trim().length < 1;
}
And add a little more falsiness to the mix, yielding the final (simplified) version:
function isNullOrWhitespace( input ) {
return !input || !input.trim();
}
It's easy enough to roll your own:
function isNullOrWhitespace( input ) {
if (typeof input === 'undefined' || input == null) return true;
return input.replace(/\s/g, '').length < 1;
}
no, but you could write one
function isNullOrWhitespace( str )
{
// Does the string not contain at least 1 non-whitespace character?
return !/\S/.test( str );
}
Try this out
Checks the string if undefined, null, not typeof string, empty or space(s
/**
* Checks the string if undefined, null, not typeof string, empty or space(s)
* #param {any} str string to be evaluated
* #returns {boolean} the evaluated result
*/
function isStringNullOrWhiteSpace(str) {
return str === undefined || str === null
|| typeof str !== 'string'
|| str.match(/^ *$/) !== null;
}
You can use it like this
isStringNullOrWhiteSpace('Your String');
You must write your own:
function isNullOrWhitespace(strToCheck) {
var whitespaceChars = "\s";
return (strToCheck === null || whitespaceChars.indexOf(strToCheck) != -1);
}
trim() is a useful string-function that JS is missing..
Add it:
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,"") }
Then: if (document.form.field.value.trim() == "")
Pulling the relevant parts of the two best answers, you get something like this:
function IsNullOrWhitespace(input) {
if (typeof input === 'undefined' || input == null) return true;
return !/\S/.test(input); // Does it fail to find a non-whitespace character?
}
The rest of this answer is only for those interested in the performance differences between this answer and Dexter's answer. Both will produce the same results, but this code is slightly faster.
On my computer, using a QUnit test over the following code:
var count = 100000;
var start = performance.now();
var str = "This is a test string.";
for (var i = 0; i < count; ++i) {
IsNullOrWhitespace(null);
IsNullOrWhitespace(str);
}
var end = performance.now();
var elapsed = end - start;
assert.ok(true, "" + count + " runs of IsNullOrWhitespace() took: " + elapsed + " milliseconds.");
The results were:
RegExp.replace method = 33 - 37 milliseconds
RegExp.test method = 11 - 14 milliseconds
You can use the regex /\S/ to test if a field is whitespace, and combine that with a null check.
Ex:
if(textBoxVal === null || textBoxVal.match(/\S/)){
// field is invalid (empty or spaces)
}

How to check if a variable inside an object that's inside another object is set (js)?

I'd like to do this:
if(a.b.c) alert('c exists') //produces error
if(a && a.b && a.b.c ) alert('c exists') //also produces ReferenceError
The only way I know of to do this (EDIT: This apparently is the only way):
if(typeof(a) != "undefined" && a.b && a.b.c) alert('c exists');
or some type of function like this...
if(exists('a.b.c')) alert('c exists');
function exists(varname){
vars=varname.split('.');
for(i=0;i<vars.length;i++){
//iterate through each object and check typeof
}
}
//this wont work with local variables inside a function
EDIT: SOLUTION BELOW
(Credit to this thread by Felix, I just adapted it a little
Check if object member exists in nested object)
This works:
if (typeof a != 'undefined' && a.b && a.b.c) alert('c exists')
But the best thing I found is to put it into a function. I use 2 different functions, one to get a variable deep in an object, and one just to check if its set.
/**
* Safely retrieve a property deep in an object of objects/arrays
* such as userObj.contact.email
* #usage var email=getprop(userObj, 'contact.email')
* This would retrieve userObj.contact.email, or return FALSE without
* throwing an error, if userObj or contact obj did not exist
* #param obj OBJECT - the base object from which to retrieve the property out of
* #param path_string STRING - a string of dot notation of the property relative to
* #return MIXED - value of obj.eval(path_string), OR FALSE
*/
function getprop(obj, path_string)
{
if(!path_string) return obj
var arr = path_string.split('.'),
val = obj || window;
for (var i = 0; i < arr.length; i++) {
val = val[arr[i]];
if ( typeof val == 'undefined' ) return false;
if ( i==arr.length-1 ) {
if (val=="") return false
return val
}
}
return false;
}
/**
* Check if a proprety on an object exists
* #return BOOL
*/
function isset(obj, path_string)
{
return (( getprop(obj, path_string) === false ) ? false : true)
}
Try this:
if (a && a.b && a.b.c)
How about this:
function exists(str, namespace) {
var arr = str.split('.'),
val = namespace || window;
for (var i = 0; i < arr.length; i++) {
val = val[arr[i]];
if ( typeof val == 'undefined' ) return false;
}
return true;
}
Live demo: http://jsfiddle.net/Y3KRd/
How about double-banging the evaluation?
if (!!a && !!a.b && !!a.b.c)

Categories