Search code examples
javascriptgoogle-chromegoogle-chrome-extension

Chrome extension update extension'sview after execute background script


I would like to show a div with the response of the server in the extension's tab. My problem is that the div is not defined in my background.js.

I use this code to execute some functions :

  saveButton.addEventListener('click', async () => {
    let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

    chrome.scripting.executeScript({
      target: { tabId: tab.id },
      function: saveProperty,
     });
  });

My problem is that my div is not defined in the "saveProperty" function.

EDIT

The div is defined in the extension's tab.

let showError = document.getElementById('showError');

The saveProperty function is used to get the content of a webpage and save in a database software.

This extension is used to make webscraping.

function saveProperty() {
  chrome.storage.sync.get(
    ['api_key', 'current_table'],

    [...]

    function sendData() {
      let req = new XMLHttpRequest();
      req.open("POST", url, true);
      req.setRequestHeader('Content-Type', 'application/json');
      req.addEventListener("load", function () {
        if (req.status >= 200 && req.status < 400) {

          // I get the error : showError is not defined.
          showError.textContent = 'Saved';
          showError.style = 'display:block';
          showError.style.backgroundColor = '#6dae24';
          setTimeout(function() {
            showError.style = 'display:none';
          }, 1500);

        } else {
          console.error(req.status + " " + req.statusText + " " + url);
          console.error(req.responseText);
        }
      });
      req.addEventListener("error", function () {
        console.error(req.responseText);
      });
      req.send(json);
    }
  });
}

Thank you very much for your help !


Solution

  • executeScript runs the code in a different page (the web page) which naturally doesn't have that div element.

    The solution is to handle that div in its page. For example, your injected function can send a message:

    saveButton.addEventListener('click', async () => {
      const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
    
      chrome.runtime.onMessage.addListener(function onMessage(msg, sender) {
        if (sender.tab?.id === tab.id) {
          chrome.runtime.onMessage.removeListener(onMessage);
          Object.assign(document.getElementById('showError'), msg.props);
        }
      });
    
      chrome.scripting.executeScript({
        target: {tabId: tab.id},
        function: saveProperty,
      });
    });
    
    function saveProperty() {
      //............
      if (ok) {
        chrome.runtime.sendMessage({
          props: {
            textContent: 'Saved',
            style: 'display:block; background-color: #6dae24',
          },
        });
      }
    }