I have a script that should get a value from the backgroud, basically it returns an item, but also for some reason it returns true when the function is called again.
In a background script item always object or undefined. How it got true in response is a mystery to me
market.js
async function renderMarketItem(item) {
//parsers name, type and quality of item
let market_item = await new Promise((resolve, reject) => {
if (chrome.runtime?.id) {
chrome.runtime.sendMessage({
action: "getMarketItem",
name: formatData(type, name, quality)
}, (item) => {
resolve(item);
})
} else resolve(undefined);
});
//another logic
}
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action == 'updateConfig') {
$('.items-grid').children().each(function() {
renderMarketItem($(this));
})
}
});
/*for example*/
$('.items-grid').children().each(function() {
renderMarketItem($(this));
})
background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action == 'getMarketItem') {
sendResponse(getMarketItem(message));
}
if (message.action == 'updateConfig') {
updateConfig(message, sender, sendResponse);
}
});
const updateConfig = (message, sender, sendResponse) => {
const {data} = message;
getTabs((tabs) => {
tabs.forEach((tab) => {
chrome.tabs.sendMessage(tab.id, { action: 'updateConfig', data });
});
});
}
let getTabs = (callback = ()=>{}) => {
chrome.tabs.query({ url: /*siteUrl*/ }, (tabs) => {
callback(tabs);
});
}
const getMarketItem = (message) => {
let targetName = message.name;
let item;
if (targetName) item = items.find(item => item.market_hash_name.trim() == targetName.trim());
return item;
}
I did function async with return true and it didn't work
Problem was in my popup react app
useEffect(() => {
const handleMessage = async (message: any, sender: any, sendResponse: () => void) => {
if (message.action === 'getConfig' && message.data) setConfig(message.data);
return true;
};
runtime.onMessage.addListener(handleMessage);
runtime.sendMessage({ action: 'needConfig' });
return () => {
runtime.onMessage.removeListener(handleMessage);
};
}, []);
This listener interrupted the listener from the content script and when the popup was opened it returned true.
I removed the listener and used the one-time request pattern where the response is returned by sendMessage:
useEffect(() => {
const getConfig = async() => {
let cfg = await runtime.sendMessage({ action: 'getConfig'});
console.log(cfg);
setConfig(cfg);
}
getConfig();
}, []);