-1

Updated: this is @ViewSource solution which is correct, except you need a return true in background.js as shown.

I have a problem in my chrome extension design which I cant find a fix for no matter how many ways I configure it.

In my popup.js I have a button a button click event like this:

document.getElementById('btnUpload').addEventListener('click', function() {

    sendDocMsg(windowUrl);

});

}

function sendDocMsg() {

    chrome.runtime.sendMessage({url: decodeURIComponent(windowUrl)},     
    function(response){
        currentHTML = response.data;

 });

and in the background I have a handler for this:

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse)    {
     var url= message.url;
     var doc = null;
     script = getScript(url);
     if(script!=null) {
        chrome.tabs.query({active: true, currentWindow: true},     function(tabs){
           chrome.tabs.sendMessage(tabs[0].id, {action: "getDocument", data:script}, 
               function(response) {
                  doc=response.data;
                  sendResponse({data: doc});
           });  
        });
     }  
return true;           

});

which should send the data from the content page back to popup.js (via background page), but for some reason, I'm getting:

Error in event handler for (unknown): TypeError: Cannot read property 'data'     of undefined
at chrome-extension://kpcmhhlcnclcnahkpjpaejaccponfble/popup.js:125:31

I have set a breakpoint in the background, and the correct data is being set on the response. I initially had a function call from popup to background using chrome.extension.getBackgroundPage()

becuase I read that this was the preferred way for popup to contact background, but this caused other issues.

Can anyone see why the data would be returned to popup.js please?

user1532510
  • 69
  • 1
  • 9
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Makyen Oct 09 '16 at 18:20
  • Possible duplicate of [Chrome Extension Message passing: response not sent](http://stackoverflow.com/questions/20077487/chrome-extension-message-passing-response-not-sent) – Marco Bonelli Oct 09 '16 at 23:00
  • @Makyen actually, [this](http://stackoverflow.com/questions/20077487/chrome-extension-message-passing-response-not-sent) should be the real duplicate. – Marco Bonelli Oct 09 '16 at 23:01
  • @MarcoBonelli, The code in the question changed from when I voted to close and when you did. With the original code, the duplicate I used was accurate. With the new code (appears to be copied from [ViewSource's answer](http://stackoverflow.com/a/39946435/3773011), without attribution), the duplicate you link to is better. – Makyen Oct 09 '16 at 23:32
  • 1
    @user1532510, If you copy things from Stack Overflow (e.g. code from [ViewSource's answer](http://stackoverflow.com/a/39946435/3773011)) you **must** provide attribution when doing so. Not providing attribution is plagiarism and a violation of the [Terms of Service](http://stackexchange.com/legal), [attribution required](http://blog.stackoverflow.com/2009/06/attribution-required/). – Makyen Oct 09 '16 at 23:38
  • @Makyen you're right, didn't see the older version and the timestamp of your comment, thanks for the clarification – Marco Bonelli Oct 09 '16 at 23:41
  • Sorry, did not mean to pass of @ViewSource answer as my own. I'm new to SO and didn't know how to show that I have used his solution and it didn't quite work - until I added a return true in the background handler as suggested by wOxxOm – user1532510 Oct 09 '16 at 23:48
  • 1
    @user1532510, Refining your question to be more understandable is good. Changing your question enough such that different answers should be supplied (particularly once you have an answer, especially if the change invalidates Answer(s)) is not something that is considered acceptable on Stack Overflow. It is understood that your problem may evolve such that you have not solved your overall problem, but that your Question, as stated in your Question text, is answered. In which case, you should write a new question (perhaps with a link back to the prior question for context).(continued) – Makyen Oct 10 '16 at 00:01
  • @user1532510, (continued) An actual answer should *not* be edited into your Question. In this case, where you have an answer which does not quite work: You should leave your question as it was originally, perhaps with clarification as to the *Question*, but not including an Answer within the Question). ViewSource should be given some time (amount indeterminate, but at least hours after the comment) to update their answer based on comments (as you have, you should comment that `return true` is needed).(continued) – Makyen Oct 10 '16 at 00:03
  • @user1532510, (continued) If they do update the answer with `return true;` then accept that answer (and vote-up). If they don't update their answer, then create your own Answer with the code you used. Provide attribution to both ViewSource and wOxxOm (for the code and need for `return true`, respectively). Vote-up ViewSource's answer (it was helpful) and accept your answer (self answers are encouraged, when you have solved the problem yourself). – Makyen Oct 10 '16 at 00:04
  • @user1532510, BTW: If you want a specific person to be notified of your comment, you need to include their ID in your comment with an @ in front of it. For instance, for me it would be `@Makyen`. If you do this as the first thing in your comment the system will provide auto-complete suggestions from those who have already posted comments on that answer/question. The original poster of the answer/question on which you are commenting will always be notified. This [meta post](http://meta.stackexchange.com/a/43020/271271) has more information. – Makyen Oct 10 '16 at 00:08

1 Answers1

0

Communication within the extension works by using Message Passing. Use the background as a middleman between the content script and the popup.

  1. Call the background page from popup using chrome.runtime.sendMessage.
  2. Add a listener in the background page using chrome.runtime.onMessage.addListener.
  3. Inside the listener insert your call to content script.
  4. Send response to popup by using sendResponse() inside the callback function.

Your new code should look something like this:

popup.js:

chrome.runtime.sendMessage({url: decodeURIComponent(windowUrl)}, function(response){
  currentHTML = response.data;
});

background.js:

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
     var url= message.url;
     var doc = null;
     script = getScript(url);
     if(script!=null) {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
           chrome.tabs.sendMessage(tabs[0].id, {action: "getDocument", data:script}, 
               function(response) {
                  doc=response.data;
                  sendResponse({data: doc});
           });  
        });
     }     
     return true;        
});
ViewSource
  • 76
  • 1
  • 4
  • 2
    `return true` is required, see https://stackoverflow.com/documentation/google-chrome-extension/2185/message-passing/7152/send-a-response-asynchronously#t=201610092201108696984 – wOxxOm Oct 09 '16 at 22:01
  • Many thanks to both of you, both needed to get the code running. – user1532510 Oct 09 '16 at 23:50