11

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.

Aryan Beezadhur
  • 4,503
  • 4
  • 21
  • 42
Samantha J T Star
  • 30,952
  • 84
  • 245
  • 427

6 Answers6

14

value[i].keyword.startsWith("keyword") because the parameter of start 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]);
}
Aryan Beezadhur
  • 4,503
  • 4
  • 21
  • 42
kevin ternet
  • 4,514
  • 2
  • 19
  • 27
  • parameter of start with must be a string ... or a variable containing anything that can be turned ino a string? like undefined for example `String(undefined)` – Thomas Aug 07 '16 at 10:57
  • Yes you're right. All the more so since the null value test become irrelevant. well done. I've just fixed my code this way – kevin ternet Aug 07 '16 at 11:55
5

Found a useful article on this topic

The three approaches for converting to string are:

  1. value.toString()
  2. "" + value
  3. String(value)

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);
Samra
  • 1,815
  • 4
  • 35
  • 71
4

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.

Thomas
  • 11,958
  • 1
  • 14
  • 23
2

I fixed this by calling value.toString().startsWith(...)

Yossi Shasho
  • 3,632
  • 31
  • 47
1

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?

Community
  • 1
  • 1
Anton Bessonov
  • 9,208
  • 3
  • 35
  • 38
1

There's a definitely obvious problem.

(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

Proxxa
  • 11
  • 1