1

I am trying to make a chrome extension that displays different text in the popup depending on what website you are on.

When the extension icon is clicked, popup.js asks background.js for the current website and if it is a "productive" one (defined explicitly in the code). Depending on what returns, popup.js uses .innerHTML to change the text in popup.html, either to "Productive Site" or "Unproductive Site"

All the code works except for one bug. When switching between a "productive" and "unproductive" site, pressing the extension icon the first time shows the old status. Pressing it a second time updates the popup's text to the correct status.

For example, if "facebook.com" is considered unproductive and "google.com" is considered productive. Opening google.com and clicking the extension icon shows "productive site". Then opening facebook.com and click the icon shows "productive site". Closing the popup and opening it again correctly shows "unproductive site".

I think this is the issue: Although I call the popup.js script first before loading the rest of the html content, it takes a longer time to get the information. By the time it returns, the popup content has already loaded using the previously known text for "productive/unproductive".

This is my first time working with javascript or html so I'm pretty lost. Any help is greatly appreciated. Thanks!

popup.html:

<script src="popup.js"></script>
<html>
<head>
    <title>Site Popup</title>
</head>
<body>
    <p> This text should change: </p>
    <p id = "test" > text</p>
</body>
</html>

popup.js:

chrome.runtime.getBackgroundPage(function (backgroundPage) {
  if (backgroundPage.getSite()) {
   document.getElementById("test").innerHTML = "Unproductive Site";
  } else {
  document.getElementById("test").innerHTML = "Productive Site";

relevant code in background.js:

var hostName
function getCurrentTab() {
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    var tab = tabs[0];
    var tabURL = tab.url; // gets url of current tab
    hostName = getHostName(tabURL);  // gets host name of the url
  } 
  )};

function getSite() {   // used in popup.js
  getCurrentTab();
  return isUnproductiveSite(hostName); // checks if the current hostName is one of the listed "unproductive" sites.
                                       // Returns true if unproductive, false if not.
}

Update (In Response to the Comments)

You're right, I wasn't considering the asynchronous aspect of it. However I'm still very confused about how to pass the values. I've looked more into callback functions but they haven't helped in my specific case. I realized the code can be simplified to this:

background.js

function getCurrentTab() {
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    var tab = tabs[0];
    var tabURL = tab.url;
    var hostName = getHostName(tabURL);
    var isUnprod = isUnproductiveSite(hostName)
  }
  )};

popup.js

chrome.runtime.getBackgroundPage(function (backgroundPage) {
    var result = backgroundPage.getCurrentTab());

The actual result in popup.js is undefined, and I realize that's because getCurrentTab doesn't have anything to return. My question is: how do I send the value of isUnprod to popup.js? I tried using a callback function but it didn't help with passing the value from background.js to popup.js

Thanks again for the help.

Carsen
  • 31
  • 3
  • Is the value that isUnproductiveSite returns correct when the popup shows the incorrect status? If not, I would guess it has to do with the syncronicity of chrome.tabs.query. – kainC Jan 01 '18 at 02:14
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – wOxxOm Jan 01 '18 at 02:43
  • Chrome API invokes the callbacks asynchronously, see the linked thread for solutions. – wOxxOm Jan 01 '18 at 02:44

0 Answers0