Access DOM from popup.js | Chrome Extension

I'm trying to make a Chrome Extension that will take some of the contents of a page (The inner HTML of a <span> with id="productTitile") I then would need to take that value and put it into a field in my popup.html.

I have tried this:

document.getElementById('input_87').value = chrome.tabs.executeScript({
    code: 'document.getElementById("productTitle").innerHTML'
});

But it just returns undefined into the field. I then ran document.getElementById("productTitle").innerHTML in the console in the parent page, and it gave me the expected value, but when I ran the whole code in console of the popup extension, it again returned undefined.

What am I doing wrong?

Upvotes: 5

Views: 1675

Answers (1)

Xan
Xan

Reputation: 77551

First off, as Haibara Ai says, chrome.tabs.executeScript is asynchronous - it doesn't return anything (and doesn't do anything immediately).

A good source on this in general is this question: How do I return the response from an asynchronous call? (spoiler: you can't)

If you look at the docs (which, by the way, should be your first unconditional reflex), you'll see that it has a callback and if you read the above question you'll understand it's your only option. However, there are 2 additional complications:

  1. The callback gets an array of results. That happens because executeScript can, optionally (with allFrames: true or frameId specified), run in subframes. So you'll need to use the first element of the results array:

    chrome.tabs.executeScript({
      code: 'document.getElementById("productTitle").innerHTML'
    }, function(results) {
      document.getElementById('input_87').value = results[0];
    });
    
  2. The call to executeScript can fail - for example, when the page is not scriptable regardless of permissions, such as the Chrome Web Store. It's wise to check that you actually got the result before using it:

    chrome.tabs.executeScript({
      code: 'document.getElementById("productTitle").innerHTML'
    }, function(results) {
      if (chrome.runtime.lastError) {
        // Couldn't execute the script at all
      } else if (typeof results[0] === "undefined") {
        // Couldn't find what we wanted
      } else {
        // Everything is fine
        document.getElementById('input_87').value = results[0];
      }
    });
    

Upvotes: 6

Related Questions