javascripttabschrome-extension-manifest-v3react-google-charts

Error with getting ID of current tab in Google Chrome extension in Manifest V3: Uncaught TypeError: Cannot read properties of undefined (reading 'id')


I am currently attempting to create a Google Chrome extension in Manifest V3 and keep encountering the following error:

Uncaught TypeError: Cannot read properties of undefined (reading 'id')

I've searched far and wide and every solution I've found just leads me to stumble into a slightly different error. I'm still pretty new with Javascript, so I'm sure this is just a super noob mistake I'm making, but here is all of my code anyways:

index.html

<html>
    <head>
        <link rel="stylesheet" href="styles.css">
        <link rel="chart" href="Chart/setup.js">

        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@700&display=swap">
        <link rel="stylesheet"
            href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
        <script type="js/main.js" src="https://www.gstatic.com/charts/loader.js"></script>
    </head>
    <body>
        <div id="donutchart" style="width: 900px; height: 500px;"></div>
        <h4>GOOGLE CALENDAR</h4>
        <h5>Time Tracker</h5>
        <hr></hr>
    </body>
</html>

manifest.json

{
    "manifest_version": 3,
    "name": "Google Calendar Time Tracker",
    "description": "Base Level Extension",
    "version": "1.0",
    "action": {
        "default_popup": "index.html",
        "default_icon": "hello_extensions.png"
    },
    "background": {
        "service_worker": "js/main.js"
    },
    "permissions": [
        "scripting",
        "tabs",
        "https://*/*",
        "http://*/*"
    ]
}

main.js

function getTabId() {
    let tabs = chrome.tabs.query({currentWindow: true, active : true});
    return tabs[0].tabId;
}

chrome.scripting.executeScript({
    target: {tabId: getTabId()},
    files : ["chart.js"],
})
.then(() => console.log("Script injected"));

chart.js

google.charts.load("current", { packages: ["corechart"] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
    var data = google.visualization.arrayToDataTable([
        ['Task', 'Hours per Day'],
        ['Work', 11],
        ['Eat', 2],
        ['Commute', 2],
        ['Watch TV', 2],
        ['Sleep', 7]
    ]);

    var options = {
        title: 'My Daily Activities',
        pieHole: 0.4,
    };

    var chart = new google.visualization.PieChart(document.getElementById('donutchart'));
    chart.draw(data, options);
}

Any other suggestions for improvements are more than welcome! As of now, all I'm trying to do is import the Google Charts library successfully, and have a pi chart display within my extension. I didn't include the stylesheet in the code above, since I didn't think it would be necessary.

I've tried changing id to tabId, and tried with promises as well, and none of that has worked and I've just had errors being thrown left, right, and center. It seems like the id / tabId variable just isn't being recognized at all, but all solutions I saw online utilized it. What am I missing here?


Solution

  • The main problem is that you don't need main.js and executeScript because its purpose is to inject scripts into the web page, whereas you need the script in the action popup, which is neither a web page nor related to it. The action popup is a separate page shown in a separate window with its own URL like chrome-extension://id/popup.html.

    To load scripts in the popup you simply write a script tag with src:

    <script src="chart.js"></script>
    <script src="popup.js" defer></script>
    

    Other problems:

    Problems in the no longer necessary main.js: