6

In this snippet I'm attempting to extract a substring from the href from a link.

let current_link = $(data, ownerDocument).find('#footbar>span>a[href^="/shortlinks"]').attr('href');
let current_number = current_link.substr(current_link.indexOf('/dex/')+5);

For some reason, when I break on the second and evaluate the line in the console, I get the substring I am expecting, but when I let the script run without a breakpoint, I get the following error:

jQuery.Deferred exception: current_link.substr(...) is not a function
TypeError: current_link.substr(...) is not a function

I added some debugging to prove to myself that current_link is actually a string:

let current_link = $(data, ownerDocument).find('#footbar>span>a[href^="/shortlinks"]').attr('href');
console.log(typeof(current_link)) // debugging
console.log(Object.getPrototypeOf(current_link)); // debugging
let current_number = current_link.substr(current_link.indexOf('/dex/')+5);

The two console.log lines printed out:

> string
> String {"", constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ, …}
>     anchor: ƒ anchor()
      ...
>     substr: ƒ substr()
      ....
>     __proto__: Object
>     [[PrimitiveValue]]: ""

I have reviewed three questions that are similar, but that I don't think apply, since by the prototype I know that current_link is a string:

EDIT: I made a jsfiddle that demonstrates the structure of the code where this is occurring. Unfortunately the error is not reproduced in the fiddle, but hopefully showing the structure helps. Fiddle

I can't link to the page where this code is running, because it is part of a TamperMonkey userscript and so is not normally part of the webpage.

SECOND EDIT: This is not actually a problem related to the substring function or string. I needed a semicolon at the end of let current_number = ... to avoid issues with Automatic Semicolon Insertion (ASI).

Jon G
  • 135
  • 4
  • does String(current_link) casting working ? – Monster Brain Jul 02 '20 at 17:31
  • 1
    It seems like a problem with async code. Please provide your actual code in a [mcve]. – str Jul 02 '20 at 17:33
  • @MonsterBrain, no that doesn't work. I tried that and current_link.toString() – Jon G Jul 02 '20 at 18:07
  • It's likely that you *think* it's defined, but it's not. Before that code try `console.log(typeof(current_link))` to check. That's a lot more readable than the prototype stuff. – tadman Jul 02 '20 at 18:23
  • @tadman Adding that line after `let current_link ...` printed `string` to the console – Jon G Jul 02 '20 at 18:29
  • Do you get that "not a function" error immediately after that, or later on? Are you sure that's the call that's failing and not some other location? – tadman Jul 02 '20 at 18:29
  • I noticed that it says `current_link.substr(...) is not a function` and not `current_link.substr is not a function`. Is there some possibility that the result is somehow called as function? Maybe passed as a parameter that expects a callback? Or maybe this happens in another place and not here? – CherryDT Jul 02 '20 at 18:44
  • @CherryDT Good eye! I notice in the fiddle there is a lot of reliance on ASI. The next line might start with parentheses in the actual code? – Klaycon Jul 02 '20 at 18:46
  • @Klaycon - Yes it does! The next line is: ```(foo[bar] = foo[bar] || []).push(...)``` I added a semicolon at the end of `let current_number ...` and that fixed it! – Jon G Jul 02 '20 at 18:57
  • 1
    @JonG Glad that fixed it. With this information I think that duplicate target is appropriate :) – Klaycon Jul 02 '20 at 19:01

0 Answers0