I’ve read the documentation over and over but I find it confusing.
What I’m trying to do is send a list of links to my background script to do some fetch requests, and then pass the response codes for those links to either popup.js or content-script.js so that I can highlight each link depending on its status
// popup.js
chrome.runtime.sendMessage({ message: filteredLinks }, (response) => {
console.log("HTTP CODES -->", response.message);
})
// background.js //
chrome.runtime.onMessage.addListener(
(request, sender, sendResponse) => {
let messReps = [];
let rep = request.message;
for (i = 0; i < rep.length; i++) {
fetch(rep[i], {
method: 'GET',
mode: 'cors'
})
.then(response => messReps.push(response.status))
}
console.log("MESS REPS", messReps);
sendResponse({ message: messReps })
return true;
});
When I log ‘messReps’ it shows all of the messages’ response codes, but when I try to send them back via sendResponse() I end up with an empty array.
I thought that the ‘return true;’ statement was supposed to hold off on sending until the function was complete, so I’m not sure what I’m doing wrong.
>Solution :
fetch runs asynchronously after the subsequent code completes, so your sendMessage is called before any requests are actually made.
Use Promise.all:
// popup
chrome.runtime.sendMessage({cmd: 'fetch', urls: filteredLinks}, res => {
console.log('HTTP CODES -->', res);
});
// background script
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.cmd === 'fetch') {
Promise.all(msg.urls.map(fetchUrl)).then(sendResponse);
return true;
}
});
async function fetchUrl(url) {
try {
return (await fetch(url)).status;
} catch (err) {
return `${err}`;
}
}