1

I'm writing a simple extension for my own use. It basically binds to a field on a web page and preforms an action when you click into the field or out of it. This is working fine.

The issue I have is the extension has some configuration fields that need to be populated. When the extension icon is clicked the config page is shown and includes some js to read and save the settings.

For example.

When the page loads I read the values. This is one example:

chrome.storage.sync.get("id", function(items) {
    if (!chrome.runtime.error) {
        id = (typeof(items.id) != "undefined" && items.id !== null) ? items.id : '';
        document.getElementById("id").value = id; 
    }
});

Once the config pages save button is clicked the values are saved.

var id = document.getElementById("id").value;
    chrome.storage.sync.set({ "id" : id }, function() {
        if (chrome.runtime.error) console.log("Runtime error.");
});

and the config page is closed:

window.close();

As the values were originally loaded with the page, the new values won't go live until the page is reloaded.

Is there anyway to either force the use of the new values, or reload the active tab ?

Thanks

UPDATE

I've tried adding the following to my background page and I can see the change, but it doesn't seem to update the variable live.

chrome.storage.onChanged.addListener( function( changes ) {
    console.log( changes );
    id = changes.id
});

When the id is invalid I should get an error message. But checking the console it's still sending the original id, not the new updated on.

How do I resolve this ? Thanks

I've updated as follows:

chrome.storage.onChanged.addListener(changes => {
  
    updateId(changes.id.newValue);
  
});


function updateId(data) {
  
  id = data
  console.log (' ID = ' + id )
}

The console.log shows the new id but the script is still using the old id.

What am I missing ? Thanks

Update

This is a breakdown of what my current code does. The popup.js is used to read and save the ID the user enters.

document.addEventListener('DOMContentLoaded', function() {
    
    chrome.storage.sync.get("id", function(items) {
        if (!chrome.runtime.error) {
            id = (typeof(items.id) != "undefined" && items.id !== null) ? items.id : '';
            document.getElementById("id").value = id; 
        }
    });
    
    var link = document.getElementById('save');
        link.addEventListener('click', function() {
        
        var id = document.getElementById("id").value;
        chrome.storage.sync.set({ "id" : id }, function() {
            if (chrome.runtime.error) console.log("Runtime error.");
        });
    
        window.close();
        
    });

});

myscript.js is used to detect the click in to and out of a specific field and then a command is passed to the background script.

    jQuery(document).ready(function() {

    helloCatAsync( function( result ) {
        id      = (typeof(result[0]) != "undefined" && result[0] !== null) ? result[0] : '';
        
        $('#siteid').focusout(function () {
            cmd = 'http://192.168.0.1/site.php?update=1&id=' + id
            
            chrome.runtime.sendMessage({ cmd }, (response) => {
                console.log(response.result);
            });
            
        });
        
        $('siteid').focusin(function () {
            cmd = 'http://192.168.0.1/site.php?clear=1&id=' + id
            
            chrome.runtime.sendMessage({ cmd }, (response) => {
                console.log(response.result);
            });
        
        });
        
        
    });

    function helloCatAsync( callback ) {
        chrome.storage.sync.get(null, function(items) {
            var allValues = Object.values(items);
            callback(allValues) ; 
        });
    }
});

eventPage.js runs the commands passed to it and returns the results. In here I've also tried to add the onChanged listener to update the value of id when it is saved.

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
    
    $.ajax({
        type: "POST",
        url: msg.cmd,
        success: function(data) {
            sendResponse({ result: data });
        },
        
        error: function(e) {
            sendResponse({ result: data });
        }
    });

    return true
    
});

chrome.storage.onChanged.addListener(changes => {
  
    updateId(changes.id.newValue);
  
});


function updateId(data) {
  
  id = data
  console.log (' ID = ' + id )
}

My aim is if the user goes into the configuration popup page and changes the id and clicks save, the new id is used straightaway, currently it requires a reload of the page.

My manifest.json contains:

"background": {
        "scripts": ["jquery.js", "eventPage.js"],
        "persistent": false
    },
  
    "content_scripts": [
    {
        "matches": ["http://*/*", "https://*/*"],
        "css": ["styles.css"],
        "js": ["jquery.js", "myscript.js"]
    }
    ],
    "icons": { 
        "16": "logo16.png",
        "48": "logo48.png",
        "128": "logo128.png"
    },
    
    "browser_action": {
        "default_icon": "logo.png",
        "default_popup": "popup.html"
    }

Thanks

Tom
  • 1,436
  • 24
  • 50
  • 1
    Use onChanged listener for chrome.storage in the content script, [example](https://stackoverflow.com/a/60154004) – wOxxOm Feb 20 '21 at 12:38
  • @wOxxOm thanks I'll take a look at this. – Tom Feb 20 '21 at 16:46
  • @wOxxOm I've tried this with no success.. I've updated the original question. Any ideas ? – Tom Feb 21 '21 at 10:57
  • [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/q/23667086) You need to do something with the changed value as shown in my example in the first comment. – wOxxOm Feb 21 '21 at 11:14
  • Still not getting this.. I've updated the original message. – Tom Feb 21 '21 at 14:51
  • Your updateId doesn't do anything with the updated variable, but you need to do something, to apply it to the site, to render something, depending on what you actually do. That's what my example does. – wOxxOm Feb 21 '21 at 15:29
  • I'm using the var `id` within the page and then passing to another external page via Ajax. I'm not sure how to update the variable so it is available to the main page. – Tom Feb 21 '21 at 18:51
  • 1
    Well, I can't help without seeing more of the code. In short you need to call some function that uses this variable. – wOxxOm Feb 21 '21 at 18:52
  • @wOxxOm Thanks for you help so far, I've added my code to the original question. – Tom Feb 22 '21 at 08:31
  • Looks like you need to call `helloCatAsync([changes.id.newValue])` in onChanged listener. – wOxxOm Feb 22 '21 at 08:49
  • I added a call to `helloCatAsync` it returned `Error in event handler: ReferenceError: helloCatAsync is not defined`. – Tom Feb 22 '21 at 11:21
  • You need to move this function into the common scope so it's available in onChanged (or in global scope) or you need to move onChanged block into the same scope. There are lots of tutorials/articles about scopes in JS if you need more info. – wOxxOm Feb 22 '21 at 12:40
  • @wOxxOm I've spent hours reading and trying this and feel I'm going round in circles. Do you have a link that will explain this so I can get it sorted. Thanks.. yet again ! – Tom Feb 22 '21 at 18:12
  • 1
    Simply move the `function helloCatAsync` block one line down so that it starts after `});` – wOxxOm Feb 22 '21 at 18:26
  • @wOxxOm I did try that but got `Error in event handler: ReferenceError: helloCatAsync is not defined at chrome-extension://jpjjndoeaknabcnodpjcpmilmaokbpel/eventPage.js:38:2` – Tom Feb 22 '21 at 21:16
  • @wOxxOm Just added my manifest.json to the original post in case it's relevant. – Tom Feb 22 '21 at 21:19
  • 1
    Like my first comment says you need to use onChanged listener in the content script. – wOxxOm Feb 23 '21 at 05:46
  • @wOxxOm This is now working. Thanks for your help and advice. If you want to post an answer I'll be happy to accept it. – Tom Feb 23 '21 at 08:44

0 Answers0