0

Once an event is triggered in my content script, it send a message request to the background script and waits for a response.

content.js

chrome.runtime.sendMessage({ userId: userId }, function (response) {
    console.log(response);
});

background.js:

chrome.runtime.onMessage.addListener(function (
  request,
  sender,
  sendResponse
) {
  const userId = request.userId;
  if (userId) {
    fetchData(userId).then((data) => {
      sendResponse({ response: data });
    });
    return true;
  }
});

I've tried async/await, moving the "return true" to outside the if statement, but in my content script the response is either undefined (even though fetchData returns the correct data), no response, or the error "the message port closed before a response was received extension".

The flow I want is:

  1. content.js sends a message request to background.js and waits for a response
  2. background.js receives the message
  3. background.js fetches data via http request
  4. background.js sends resolved promise back to content.js
  5. content.js receives response and logs the data
  • The code is correct, so I guess your data isn't JSON-compatible or you didn't reload the extension or didn't reload the tab (the content scripts aren't re-injected automatically in Chrome, but you can do it [manually](https://stackoverflow.com/q/10994324)). – wOxxOm Apr 20 '22 at 15:05
  • @wOxxOm I can add console logs to content.js and see the changes immediately. If I log the data in fetchData().then I can see the output is correct and in JSON format. My guess was that it closes the port before it sends the response and so content.js never receives a response. If I send a response without a promise.then (just sending a string) it works. The only issue is when dealing with promises. So I'm wondering what order of fetch, send response, return true I should have. – Vendetaheist23 Apr 21 '22 at 16:25
  • That's not what my comment suggests. The first guess means the data is not string, number, boolean, or object/array of these types. The second guess is explained in the linked topic. – wOxxOm Apr 21 '22 at 17:29
  • @wOxxOm Sorry if I misunderstood, but regarding the first guess, replacing "data" with a string doesn't send a response in .then(), but it works when I send it outside the fetchData() call. Console logging strings will output correctly before and after the sendResponse(), but then I won't receive the response in content.js. Thanks for taking your time to respond! – Vendetaheist23 Apr 23 '22 at 06:29
  • Sounds like fetchData is not returning Promise correctly. – wOxxOm Apr 23 '22 at 09:08
  • @wOxxOm thanks for all your help! Just posted an answer to the problem. – Vendetaheist23 Apr 26 '22 at 03:19

1 Answers1

0

The issue turned out to be changing tabs in the popup before the response was received. I fixed it by moving the command to change the popup tab (window.open()) to be in the response, after processing the response data.