1

I'm brand new to js and making a chrome extension and I want to take a message from the background.js and use it in the popup.js after I click a button.

popup.js

window.onload=function(){
    document.getElementById("BTC").addEventListener("click", bitcoin);
}
function bitcoin(){
  console.log("Clicked!");
  chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse){
    if(msg.greeting == "BTC"){
      var prices = msg.data;
      console.log(prices);
      sendResponse({});
      }
  });
}

background.js

function coinArray(coins){
      console.log(coins);
      for (var i = 0; i < 12; i++){
            var prices = new Array();
            prices[i] = coins[i].price_usd;
      }
chrome.runtime.sendMessage({greeting: "BTC", data: prices}, function(response)  {});
}

I expect to see an array of the top 12 cryptocurrencies' prices from Coinmarketcap.com as an array in my popup console when I click the "BTC" button. I can console.log it in background.js no problem. The function coinArray is called when I load the data from the online API which is an XMLHTTPRequest not shown in the code.

Currently, only the "Clicked!" is coming through on the other end and I feel as if the problem might be that the onMessage line is within the function itself? Not sure where to go from here after looking up solutions to this problem. Any Clarity would be much appreciated!

Colin
  • 13
  • 4
  • 1
    Can you take `chrome.runtime.onMessage.addListener` outside of the function? – Aefits Dec 20 '18 at 05:00
  • 1) the listener should be added at the start of the popup script. 2) the background page runs long before before the popup is shown if it's not "persistent": false in manifest.json, otherwise it won't run at all after being suspended once as there's nothing to wake it up, 3) it's not clear what the goal is here so maybe you don't need the background script. 4. Start using devtools debugger: each component of an extension has its own separate devtools window where you can set breakpoints, pause execution, inspect the variables and code flow. – wOxxOm Dec 20 '18 at 05:46

1 Answers1

1

To frame your problem in intuitive terms: you're trying to make the background page "shout" first (whenever that coinArray function happens to run) but start listening for the "shout" later, after there's no sound anymore.

sendMessage is an active action, that should happen while onMessage is already (passively) listening, or it won't work ― it won't be "waiting" for you to start listening.

You need to reverse your logic here. Make the popup request the data from the background page with a sendMessage, which the background page can always listen to. You can then use sendResponse to deliver an answer to the popup.

  1. Background registers an onMessage listener, waiting for the popup message.
  2. User opens the popup and clicks the UI there.
  3. Popup calls sendMessage for information.
  4. Background receives the request, obtains the data needed (however that works in your case) and calls sendResponse with the data.
  5. In the popup, the sendMessage callback is called with the data provided.

Of course, the exact implementation depends on how you retrieve the data. It's likely asynchronous, so don't forget to return true in the message listener so that sendMessage() can be called later. And in general, take a longer read of the Messaging docs and chrome.runtime docs.

Xan
  • 74,770
  • 16
  • 179
  • 206