Reputation: 32848
I have this code:
for (var i = 0; i < value.length; i++) {
if (typeof value[i].keyword == 'undefined' || value[i].keyword == null || value[i].keyword.startsWith(keyword)) {
out.push(value[i]);
}
}
I am getting an error message saying:
> TypeError: r[e].startsWith is not a function > at js-cf2cc68….min.js.gz:85 > at fn (eval at compile (js-cf2cc68….min.js.gz:8), <anonymous>:4:1003) > at js-cf2cc68….min.js.gz:7 > at p.$digest (js-cf2cc68….min.js.gz:7) > at p.$apply (js-cf2cc68….min.js.gz:7) > at HTMLBodyElement.<anonymous> (js-cf2cc68….min.js.gz:9)
How is this possible? I think I've accounted for everything.
Upvotes: 15
Views: 81644
Reputation: 4612
value[i].keyword.startsWith("keyword")
because the parameter of startsWith
with must be a string.
So that will work better this way
for (var i = 0; i < value.length; i++) {
if (typeof value[i].keyword == String(undefined) || value[i].keyword.startsWith("keyword"))
out.push(value[i]);
}
Upvotes: 16
Reputation: 11
(This is entirely for people who have a problem like this one, but they don't really understand)
Of course, just like many others are saying, it's in the type. If you don't know what types are (You likely do if you know this advanced type of stuff, but just in case!), its simple. The primitive types are True
/False
, Undefined
/Null
, Numbers
, and Strings
, any string
type that is not empty or numbers not equal to 0
resulting in being true
if put through an if statement
on their own. Now that we've got that out of the way, its time to talk about startsWith()
. If you run console.log("Hey VSauce, Michael here.".startsWith("Hey"))
, it would output true
to the console due to how the string starts out with a string. If you run console.log(1234.startsWith(1))
, would occur with a TypeError
due to startsWith()
requiring a string. We can tell this is a TypeError
from the error output. So, the problem above (that was already answered) was that the variable keyword
wasn't being defined as a string, but rather any other variable, and needed to be defined as a string
Upvotes: 1
Reputation: 2013
Found a useful article on this topic
The three approaches for converting to string are:
The point to note here is that approach # 1 doesn’t work if the value is null or undefined.
In my case, approach # 2 for some reason did not work either so the best option would be String(value)
var col = "rt_" + rows[i]["results"][r].ResultTypeID.substring(1); //did not work
var col = "rt_" + String(rows[i]["results"][r].ResultTypeID).substring(1);
Upvotes: 6
Reputation: 12677
Is there a way that I can check if it's a string rather than have it error out?
checking the type?
var out = values.filter(v => v.keyword == null || typeof v.keyword === "string" && v.keyword.startsWith( keyword ));
or simply enforcing the type
var out = values.filter(v => v.keyword == null || String(v.keyword).startsWith( keyword ));
or if you use desctructuring, you can use even this:
var out = values.filter({keyword: v}) => v == null || String(v).startsWith( keyword ));
I'd reccomend you to use the Array-methods instead of manually writing loops.
Imo. it is a better description of your intent (good for scanning over code).
If this is a hot path (it's called often) the JS-optimizer can take advantage of knowing, that youre'just filtering, and optimize the code. Maybe by skipping the lots of integrity-checks for the Array it performs during your loop.
And if this is not a hot-path, the performance-impact of calling a function a few times will even be hard to measure, in JS.
Upvotes: 4
Reputation: 9813
I assume value[i].keyword is a string. String.prototype.startWith is not supported in older browsers. See browser support.
To use it in older browsers, you can use one of existing polyfills. See also answers from How to check if a string “StartsWith” another string?
Upvotes: 1