3

Have a problem I can bypass but do not understand why it is so!

Trying to develop a chrome extension and send messages from the popup to the background script - no problem.

But in the background listner I am unable to send a response because the port is null just because I call a chrome.storage function first - why?

I have this helper function:

gext.getsettings = function (callback)
{
  chrome.storage.local.get('settings', function(items) 
  {
    if(callback)
    {
      if(chrome.runtime.lastError)
        callback(false);

      if(items && items['settings']) 
        callback(items['settings']);
      else
        callback(null);
    }
  });
};

that is called in chrome.runtime.onMessage.addListener

gext.getsettings(function(settings)
{                  
          if(sendResponse)
            sendResponse({result: true});           
}

When I debug the sendResponse({result: true}); I can see that the port is null and therefore it fails.

I have looked up that this is because people did not close ports and therefore Chrome have made it so that ports are closed after the first call. It shall be possible to bypass this by returning true in the prior callback functions.

In my case this is a bit complicated as I have to call the callback first before I can return true in getsettings - and this fails.

I can just move the sendResponse({result: true}); out before or after the call to getsettings and it works fine. But what if I was depending on some specific settings before I send the response - how do I achieve this?

I know I can make a permanent open port, but is the above really by design?

Beast
  • 271
  • 2
  • 5
  • 15

1 Answers1

1

I had this problem too. It was really annoying to understand why the port is null, when it should be active.

The issue is when you're listening for messages in background, you should always return true in the handler: this will keep the port alive and indicate that you'll send a response asynchronously later, using the callback sendResponse function.

For example:

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    handler(sendResponse); // a function which later will call sendResponse
    return true; // Important to return true, to keep the port alive
});

Find more details from sendResponse parameter description.

Dmitri Pavlutin
  • 18,122
  • 8
  • 37
  • 41
  • Sorry do not understand how to change my code to achieve this? I only call chrome.storage before the sendResponse so where shall I put in the return true? – Beast Feb 17 '16 at 19:57
  • To me it seam as if the call to chrome.storage.local.get close the port! – Beast Feb 17 '16 at 20:06
  • My problem - you are right. Just need to return true in the chrome.runtime.onMessage.addListener function. – Beast Feb 17 '16 at 20:21