Search code examples
javascriptgoogle-chrome-extensionparameter-passing

Chrome Extension: content_script cannot receive variable from popup.js correctly


I'm learning how to make chrome extensions.I tried to send value of the textbox in popup.html to my content_script. I got some promblem when receiving value.

Here is what I have so far:

popup.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="button.css">
  </head>
  <body>
    <p>Value1 Input:</p>
    <input type="text" id="myValue1">
    <p>Value2 Input:</p>
    <input type="text" id="myValue2">
    <p></p>
    <button id="clickactivity">Pass Value</button>
    <script src="popup.js"></script>
  </body>
</html>

popup.js

function injectTheScript() {
   
    var myValue1 = document.getElementById('myValue1').value 
    var myValue2 = document.getElementById('myValue2').value 
    var parameterArray = [];
    parameterArray.push(myValue1);
    parameterArray.push(myValue2);

    chrome.tabs.query({active: true, currentWindow: true}, tabs => {
        chrome.scripting.executeScript({target: {tabId: tabs[0].id}, files: ['content_script.js']}, 
        function() {
             chrome.tabs.sendMessage(tabs[0].id, {myVar: parameterArray});
             
        });
    })
        
}

document.getElementById('clickactivity').addEventListener('click', injectTheScript)

content_script.js

var myValue1;
var myValue2;


(function() {
    chrome.runtime.onMessage.addListener(function(message) {      
        myValue1=message.myVar[0];
        myValue2=message.myVar[1];
        console.log('myValue1 in addListener:'+myValue1);
        console.log('myValue2 in addListener:'+myValue2);

    });

})();

async function mainLoop() {
    
    console.log('into mainloop')
    console.log('myValue1 in mainLoop:'+myValue1);
    console.log('myValue2 in mainLoop:'+myValue2);
    
    ....//do something
}

mainLoop();

When I click the Pass Value button at popup.html, I come into problems below.

At first click, I set myValue1=2 and myValue2=2 in textbox, the log is:

into mainloop
myValue1 in mainLoop:undefined
myValue2 in mainLoop:undefined
myValue1 in addListener:2
myValue2 in addListener:2

At second click, I set myValue1=3 and myValue2=3 in textboxs, the log is:

into mainloop
myValue1 in mainLoop:2
myValue2 in mainLoop:2
myValue1 in addListener:3
myValue2 in addListener:3
myValue1 in addListener:3
myValue2 in addListener:3

I want to use myValue1 and myValue2 in mainLoop,but they are undefined at first click. It looks like the mainLoop run before the addListener.

At second click, both values in mainLoop are 2(I expect they both are 3). And the addListener was call twice.It looks like the mainLoop run with the value set by first click then the addListener set the value to 3.

I'd like to know how to amend my code to make content_script receive from popup and set myValue1 and myValue2 before the mainLoop run. Also, I want to know how to prevent the addListener being called more than once.Thanks.


Solution

  • Thanks to wOxxOm! Move mainLoop(); into my onMessage listener at its end solve my first problem. Both values are correct. For the scecond problem, I found and answer by using chrome.runtime.onMessage.removeListener to prevent the function being called more than once. I change my content_script.js as below and it works fine!

    content_script.js

    var myValue1;
    var myValue2;
    
    chrome.runtime.onMessage.addListener(receiveMessage);
    
    function receiveMessage(message){
            myValue1=message.myVar[0];
            myValue2=message.myVar[1];
            console.log('myValue1 in addListener:'+myValue1);
            console.log('myValue2 in addListener:'+myValue2);
            mainLoop();
            chrome.runtime.onMessage.removeListener(receiveMessage);
    }
    
    async function mainLoop() {
        
        console.log('into mainloop')
        console.log('myValue1 in mainLoop:'+myValue1);
        console.log('myValue2 in mainLoop:'+myValue2);
        
        ....//do something
    }