0

I'm sending a string message from background.js to popup.js. I do receive a message in popup.js but I can't manipulate it. I am able to view it if a alert() it or if I assign it to innerHTML of a popup.html element, but I can't assign it to any variables in popup.js so I could modify it and make use of it.

I tried regular assignment, I tried using substring() to copy the message into another variable

Here I have a piece of background.js that sends a message to popup.js. myString is a string:

chrome.runtime.sendMessage({
    action: "getSource",
    source: myString
});

Here is a piece of popup.js that receives the message once background.js is executed, the code below works, it displays the string in popup.html:

chrome.runtime.onMessage.addListener(function(request, sender) {
  if (request.action == "getSource") {
container.innerHTML = request.source;}})

This also works:

chrome.runtime.onMessage.addListener(function(request, sender) {
  if (request.action == "getSource") {
alert(request.source);}})

But when I try to assign it to a variable, I get nothing (testString is still empty):

var testString = '';

chrome.runtime.onMessage.addListener(function(request, sender) {
  if (request.action == "getSource") {
testString = request.source;}})

If I assign a value to testString outside of chrome.runtime.onMessage.addListener(...), the assignment works just fine, testString ends up being "abcde":

var testString = '';

chrome.runtime.onMessage.addListener(function(request, sender) {
  if (request.action == "getSource") {
console.log("do nothing")}});

testString = "abcde";

I want to have the contents of request.source in a variable so I could manipulate it.

Thank you.

Alex A
  • 1
  • 1
  • You should manipulate it inside the callback, not outside. – wOxxOm Feb 14 '19 at 04:39
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – rsanchez Feb 14 '19 at 15:15

1 Answers1

0

chrome.runtime.onMessage.addListener receives a callback as parameter and its return value does not come in a synchronous way. At the time you've received the message from background, the variable testString may be already assigned to "abcde" or any other value you try to assign to it after the addListener function.

You have to call another function (inside the addListener callback) which passes testString as parameter:

var testString = '';

function onMessageReceived (source)  {
   testString = source
   // do whatever you want with the value
}

chrome.runtime.onMessage.addListener(function (request, sender) {
  if (request.action === 'getSource') {
     onMessageReceived(request.source)
  }
})

Another option is to wrap the whole chrome.runtime.onMessage.addListener inside a Promise:

function onMessageReceived (source) {
  return new Promise(function (resolve, reject) {
    chrome.runtime.onMessage.addListener(function (request, sender) {
      if (request.action === 'getSource') {
         resolve(request.source)
      }

      // don't forget to reject the Promise if some condition is not satisfied
  })
}

onMessageReceive().then(function (source) {
  // variable source contains request.source value
})
herodrigues
  • 948
  • 1
  • 7
  • 11