2

I am having syncronization problem with chrome.storage.local.get

The code that works:

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log('chrome.runtime.onMessage.addListener: ', message)
    if (message.type === "NewURL") {
        console.log('background.js: start timer')
        let blockUrlList = ["youtube.com", "dict.cc"]
        /*
        chrome.storage.local.get(["block_urls"], (res) => {
            blockUrlList = "block_urls" in res ? res.block_urls : []
        })
        */
        console.log(blockUrlList)
        chrome.tabs.query({ "url": blockUrlList.map(p => `*://*.${p}/*`)}, (tabs) => {
            tabs.forEach((tab) => {
                console.log('tab.id: ',tab.id, 'tab.url:', tab.url)
            })
        })
    }
})

however, if i try to get blockUrlList from chrome storage I get blank list.

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log('chrome.runtime.onMessage.addListener: ', message)
    if (message.type === "NewURL") {
        console.log('background.js: start timer')
        let blockUrlList = []
        
        chrome.storage.local.get(["block_urls"], (res) => {
            blockUrlList = "block_urls" in res ? res.block_urls : []
        })
        
        console.log(blockUrlList)
        chrome.tabs.query({ "url": blockUrlList.map(p => `*://*.${p}/*`)}, (tabs) => {
            tabs.forEach((tab) => {
                console.log('tab.id: ',tab.id, 'tab.url:', tab.url)
            })
        })
    }
})

How can I synchronise i.e. wait for chrome.storage.local.get before proceeding to chrome.tabs.query? Also I want chrome.tabs.query to wait on it before proceeding to next line

EDIT
Though the question has been closed by the moderator. I am writing the cleanest (easiest to read) solution I learned.

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.type === "NewURL") {
        injectJS()
    }
})
async function injectJS() {   
    try {
        let blockUrlList = []
        const res = await chrome.storage.local.get(["block_urls"])
        blockUrlList = "block_urls" in res ? res.block_urls : []
        
        const qryOptions = { "url": blockUrlList.map(p => `*://*.${p}/*`)}
        const tabs = await chrome.tabs.query(qryOptions)

        tabs.forEach((tab) => {
            chrome.scripting.executeScript({
                target: {tabId: tab.id},
                files: ['content/injected.js']
            })
        })
    } catch (err) {
        console.log('No matching tab', err)
    }
}
Ani
  • 265
  • 1
  • 3
  • 10
  • FYI, your question was not closed by a moderator (moderators have a blue diamond next to their name). It was closed by a normal user with sufficient reputation in the javascript tag to be allowed to close questions tagged with [tag:javascript] as duplicate single-handedly. – Mark Rotteveel May 11 '23 at 10:24

1 Answers1

1

You can simply put it into the callback:

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log('chrome.runtime.onMessage.addListener: ', message)
    if (message.type === "NewURL") {
        console.log('background.js: start timer')
        let blockUrlList = []
        
        chrome.storage.local.get(["block_urls"], (res) => {
            blockUrlList = "block_urls" in res ? res.block_urls : []
            console.log(blockUrlList)
            chrome.tabs.query({ "url": blockUrlList.map(p => `*://*.${p}/*`)}, (tabs) => {
                tabs.forEach((tab) => {
                    console.log('tab.id: ',tab.id, 'tab.url:', tab.url)
                })
            })
        })
        
    }
})

The callback, after all is running at the very moment of your preference, i.e., when the get() has finished successfully.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175