Using .includes method in a function - javascript

I have a an object jsonRes[0] containing values which need to be removed based on a condition. The following works to remove null, missing values and those equal to zero in the stringified object:
function replacer(key, value) {
// Filtering out properties
if (value === null || value === 0 || value === "") {
return undefined;
}
return value;
}
JSON.stringify(jsonRes[0], replacer, "\t")
However, when I add a condition using the the includes method, I receive an error:
function replacer(key, value) {
// Filtering out properties
if (value === null || value === 0 || value === "" || value.includes("$")) {
return undefined;
}
return value;
}
Uncaught TypeError: value.includes is not a function
Why is this the case and is there a workaround?

You can use String.indexOf() instead of String.includes, As it is available in ES6 and not supported in IE at all.
typeof value == "string" && value.indexOf('$') > -1
Also note if value is not string type it will still raise an error boolean, Number doesn't the the method. You can use typeof to validate whether value is a string.

The .includes() API is part of the String and Array data type.
So what the error is trying to tell you is that the value for variable value, e.g. an integer or object, does not have the property .includes.
You could do checks like
typeof a_string === 'string'
an_array instanceof Array
before the .includes() api to prevent this.
Obviously this will make your if statement rather ugly due to the number of checks you have.
Based on the way your code is written I suspect you are more interested in checking "String" than array. So becareful of arrays. Your code may not work properly if it is array.
Anyway here is a refractored version of your code.
function replacer(key, value) {
// Filtering out properties
if (!value || typeof value === "string" && value.includes("$")) {
return undefined;
}
return value;
}
console.log("NULL returns:" + replacer('test', null));
console.log("$Test returns:" + replacer('test', '$test'));
console.log("Blah returns:" + replacer('test', 'Blah'));

Just one more possibility: Maybe your value is not a string type object.
(typeof(value) == "string" && value.includes("$"))

I solved this error, which I was getting when applying "includes" to a "window.location" value, by appending ".toString();"
var requestUrl = window.location.toString();
if (requestUrl.includes(urlBase + "#")) {
...

I actually am not sure what type of the variable named value is, but anyway, Array.prototype.includes and String.prototype.includes are only available in ES6. You need to use babel-polyfill or any other bundling modules like rollup.js, webpack with babel or something like that to use includes function.

Related

How to use a variable as string or object in TypeScript?

I have a variable that can either be a string or object like this:
value?: string | { name: string, type: string }
Trying something below but I get a compile error:
console.log(value?.name || value)
console.log(value?.type)
How can use this variable if it can be either type?
In this case you can do:
console.log(typeof value === 'string' ? value : value?.name)
Typescript can narrow the type using type-guards, see here for more details.
So you have two options
console.log(typeof value === 'string' ? value : value.name);
But as you used ?: in definition for this value (allowing undefined) and as i think that console is only for simple example there
if (value === undefined) {
} else if (typeof value === 'string') {
} else {
}
Would be best.
This issue you found is mostly done because both values for value variable are objects and ts saw that the types are not compatible and asks you to narrow them by hand

How to check if a value in object is a primitive?

So basically i want to check if my data (which is in JSON Format) has a value which is a primitive. So let's take an Example: I get data that looks like this: {name: Artikel, value: {"ArtNr": 1234}} and i want to check if 1234 is primitive or not. I also want to differentiate if the result is an Array with Primitives in it or an Object. Is that possible?
function isObjectContainingPrimitiveValues(test) {
let values = Object.values(test);
for (let i of values) {
console.log(i);
return (typeof i === 'string' || typeof i === 'number' || typeof i === 'boolean' || typeof i === null || typeof i === undefined);
}
}
UPDATE
So with the awesome help of MaxK i have built a isResultContainingPrimitiveValues() Function which checks my data for Primitive/ Primitive Arrays and or Objects. The following part is the trickiest at least with my understanding. The following Example will hopefully help you understand my problems better.
So my let namesSplit = treeNode.name.split('.'); variable splits the data it gets and has as a result of nameSplit : Artikel,Artnr. Next i defined a key variable let key = namesSplit[0]; which has key : Artikel as a result. Than i define a contextEntry variable let contextEntry = exprData.contextEntry.find(_x => _x.name === key); and has contextEntry : {"name":"Artikel","value":{"ArtNr":123}} as a result. Now i want to check: if there's another split namesSplit.length > 1 check isResultContainingPrimitiveValues(). If it is primitive, throw an error, if it is an object -> get values from it and if it is an array -> get values form there. I know it's a lot but from all the confusing stuff i can't seem to think clear, so i appreciate every help i can get.
You are returning from your function on the first iteration. You should only return false if you found an non-primitive and if you were able to loop over all values you can return true because all values are primitives:
function isObjectContainingPrimitiveValues(testObj) {
let values = Object.values(testObj);
for(let i of values){
if (typeof i === 'object') {
return false;
}
}
return true;
};
Update:
After reading your comment i changed the code to check for arrays with primitives as well. The idea is, to create a new function which only checks if a single value is a primitive.Now if we find an array, we can simply check - with the help
of the arrays some function - if some element, inside the array is not primitive. If so return false,otherwise we do the same checks as before:
function isObjectContainingPrimitiveValues(testObj) {
let values = Object.values(testObj);
for (let i of values) {
if (Array.isArray(i)) {
if (i.some(val => !isPrimitive(val)))
return false;
} else {
if (!isPrimitive(i))
return false;
}
}
return true;
};
function isPrimitive(test) {
return typeof test !== 'object'
}
Array and object types all return a 'typeof' 'object'. so you can check against an object instead of checking against multiple conditions.
So the return statement will be:
return (typeof i === 'object').
Number, string, undefined, null will all return false on the statement above.

How to check if variable is set && .length>x in same ()?

I want to check that a variable exists and that it its length is greater than a particular number within a single if statement. I can achieve the desired result by doing:
if(v){
if(v.length>3)
//do thing
}
But if I try to just do:
if(v.length>3)
// do thing
I bug out when v is not declared. Similarly if I try to do:
if(v&&v.length>3)
I bug out. How do I achieve the desired result most readably?
A final answer depends on how generic you want the solution. While .length is shorthand notation for looking up an object property named "length", it must be applied to an object value. But the typeof operator returns "function" for a function object, and "object" for null - which is not an object data type and will crash if you attempt to look up a property on it. Oh, and primitive string values promote to a String object with a length property.
So, a generic solution could look like
if(v && typeof v == "object" || typeof v == "function" || typeof v == "string" && v.length > 3)
{ // do stuff
}
where the test for v being truthy excludes v having a value of null. But notice that if you can exclude function objects (which have a length property giving the number of arguments they expect) and string values you could shorten this to
if(v && typeof v == "object" && v.length > 3)
Note that if the length property does not exist it will return a value of undefined and undefined > 3 is false.
Update after question comment:
if(v)
can fail in strict mode if v has never been defined. This could be the result of defining v using a let or const statement executed after the if statement. Either execute the let or const statement first or declare v using a var statement in scope of the testing code.

What is the javascript equivalant for vbscript `Is Nothing`

If Not (oResponse.selectSingleNode("BigGroupType") Is Nothing) Then
End If
I need to convert this to javascript. Is that enough to check null?
This was my lead's answer, plz verify this,
if(typeof $(data).find("BigGroupType").text() != "undefined" && $(data).find("BigGroupType").text() != null) {
}
JavaScript has two values which mean "nothing", undefined and null. undefined has a much stronger "nothing" meaning than null because it is the default value of every variable. No variable can be null unless it is set to null, but variables are undefined by default.
var x;
console.log(x === undefined); // => true
var X = { foo: 'bar' };
console.log(X.baz); // => undefined
If you want to check to see if something is undefined, you should use === because == isn't good enough to distinguish it from null.
var x = null;
console.log(x == undefined); // => true
console.log(x === undefined); // => false
However, this can be useful because sometimes you want to know if something is undefined or null, so you can just do if (value == null) to test if it is either.
Finally, if you want to test whether a variable even exists in scope, you can use typeof. This can be helpful when testing for built-ins which may not exist in older browsers, such as JSON.
if (typeof JSON == 'undefined') {
// Either no variable named JSON exists, or it exists and
// its value is undefined.
}
You need to check for both null and undefined, this implicitly does so
if( oResponse.selectSingleNode("BigGroupType") != null ) {
}
It is the equivalent of:
var node = oResponse.selectSingleNode("BigGroupType");
if( node !== null &&
node !== void 0 ) {
}
void 0 being a bulletproof expression to get undefined
In JavaScript equvalent for Nothing is undefined
if(oResponse.selectSingleNode("BigGroupType") != undefined){
}
This logic:
If Not (oResponse.selectSingleNode("BigGroupType") Is Nothing)
Can be written like this in JavaScript:
if (typeof oResponse.selectSingleNode("BigGroupType") != 'undefined')
Nothing would equal undefined, but checking against undefined is not recommended for several reasons, it’s generally safer to use typeof.
However, if the selectSingleNode can return other falsy values such as null, it’s probably OK to just do a simple check if it is truthy:
if (oResponse.selectSingleNode("BigGroupType"))
JavaScript:-
(document.getElementById(“BigGroupType”) == undefined) // Returns true
JQuery:-
($(“#BigGroupType”).val() === “undefined”) // Returns true
Note in above examples undefined is a keyword in JavaScript, where as in JQuery it is just a string.

Testing nested objects as undefined in Javascript [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
javascript test for existence of nested object key
I'm attempting to construct an error message for a formset by testing if a certain object is not undefined, and if it's not undefined, then I end up populating it with that error message. The main problem is that I have to validate if each nested object is undefined, which results in some pretty ugly code. Here's the example:
errorsForField: function(fieldName, formsetName, formNumber) {
if (typeof this.model.errors != 'undefined'){
var fieldError = document.createElement('span');
$(fieldError).addClass('field-error');
// THE FOLLOWING LINE THROWS ERROR.
if (formsetName && _.isUndefined(this.model.errors[formsetName][fieldName]) != true) {
$(fieldError).text(this.model.errors[formsetname][fieldName]);
} else if (typeof this.model.errors[fieldName] != "undefined"){
$(fieldError).text(this.model.errors[fieldName]);
}
this.errors[fieldName] = fieldError.outerHTML;
return fieldError.outerHTML;
}
return false;
},
I get an error stating that I cannot determine [fieldName] of an undefined object this.model.errors[formsetName]. In other words, I have to first determine if this.model.errors[formsetName] is empty and then test if [fieldname] is undefined.
This seems like a really cumbersome solution. Any suggestions for changing this?
You can create a library function that takes property names as parameters and returns the final value if it exists, or null:
function TryGetPropertyValue(o, propertyName1 /*, ... propertyNameN */) {
var names = [].slice.call(arguments, 1);
while (o && names.length) {
o = o[names.shift()];
}
return names.length ? null : o;
}
Call it like:
var err = TryGetPropertyValue(this.model.errors, formsetName, fieldName) ||
TryGetPropertyValue(this.model.errors, fieldName);
if (err != null) {
$(fieldError).text(err);
}
If you want it to return undefined instead of null if the field is not found, you can change the function slightly:
function TryGetPropertyValue(o, propertyName1 /*, ... propertyNameN */) {
var names = [].slice.call(arguments, 1);
while (o && names.length) {
o = o[names.shift()];
}
if (names.length == 0) {
return o;
}
}
http://jsfiddle.net/HbggQ/
As Paul suggested, this is an inherent limitation of Javascript. Even Coffeescript (which is just a layer of syntactic sugar on top of JS) doesn't really solve the problem; it just hides the workaround under it's syntactic sugar (which admittedly is really handy)
If you want to stick to Javascript, you basically have two options: use ternary operators, or use boolean operators. Here's examples of each that check A.B.C.D (where A, B, C or D might not exist):
// Returns A.B.C.D, if it exists; otherwise returns false (via ternary)
return !A ? false :
!A.B ? false :
!A.B.C ? false :
A.B.C.D ? A.B.C.D : false;
// Returns A.B.C.D, if it exists; otherwise returns false (via booleans)
return A && A.B && A.B.C && A.B.C.D;
Obviously the latter is a lot shorter. Both solutions rely on Javascript's "truthiness" (ie. that the values 0, "", null, and undefined count as false). This should be fine for your case, as none of those values will have an errors property. However, if you did need to distinguish between (say) 0 and undefined, you could use the ternary style, and replace !A with typeof(A) == 'undefined'.

Categories