Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

startsWith is not a function getting called for no reason

Tags:

javascript

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.

like image 315
Samantha J T Star Avatar asked Aug 07 '16 10:08

Samantha J T Star


People also ask

How do I fix the error startswith is not a function?

The "startsWith is not a function" error occurs when we call the startsWith () method on a value that is not a string. To solve the error, convert the value to a string using the toString () method or make sure to only call the startsWith method on strings.

Why does startswith() return a TypeError in the console?

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.

Is it possible to call a function a few times in JS?

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. 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.


5 Answers

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

like image 175
Yossi Shasho Avatar answered Nov 11 '22 12:11

Yossi Shasho


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]);
}
like image 43
kevin ternet Avatar answered Nov 11 '22 12:11

kevin ternet


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);
like image 23
Samra Avatar answered Nov 11 '22 12:11

Samra


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.

like image 28
Thomas Avatar answered Nov 11 '22 13:11

Thomas


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?

like image 38
Anton Bessonov Avatar answered Nov 11 '22 12:11

Anton Bessonov