javascriptgoogle-chromegoogle-chrome-extension

chrome.storage not saving data (chrome was used before it was defined)


I am following a youtube tutorial for making chrome extensions.

This is the Manifest file:

{
    "manifest_version":2,
    "name":"Budget Manager",
    "version":"1.0",
    "description":"This extension tracks your overall spendings.",
    "icons":{
        "128":"icon128.png",
        "48":"icon48.png",
        "16":"icon16.png"
    },
    "browser_action":{
        "default_icon":"icon16.png",
        "default_popup":"popup.html"
    },
    "permissions": [
        "storage"
    ]
}

popup.html

<!DOCTYPE html>
<html>
    <head>
        <title>Budget Manager</title>
        <script src="jquery-3.2.1.min.js">
        </script>
        <script src="popup.js">
        </script>
    </head>
    <body>
        <h1>Budget Manager</h1>
        <h2>Total Spend: <span id="total">0</span></h2>
        <h2>Limit: <span id="limit"></span></h2>
        <h3>Enter Amount</h3>
        <input type="text" id="amount"/>
        <input type="submit" id="spendAmount" value="Spend">
    </body>
</html>

popup.js

$(function() {   
    chrome.storage.sync.get('total', function (budget) {
        $('#total').text(budget.total);
    });
    $('#spendAmount').click(function() {
        chrome.storage.sync.get('total', function (budget) {
            var newTotal = 0;
            if (budget.total) {
                newTotal += parseInt(budget.total);
            }

            var amount = $('amount').val();
            if(amount) {
                newTotal += parseInt(amount);
            }

            chrome.storage.sync.set({'total': newTotal});

            $('#total').text(newTotal);
            $('#amount').val('');
        });
    });
});

I am getting errors like:
'chrome' was used before it was defined --> chrome.storage.sync.get('total', function (budget) {
Missing 'use strict' statement --> chrome.storage.sync.get('total', function (budget) {
'$' was used before it was defined --> $(function){

Also another beginner question. Why are we using chrome.storage anyways? I mean if we don't have to sync. Why can't I just use normal variables to store the data.


Solution

  • First, the non-errors

    I am getting errors like:

    'chrome' was used before it was defined -->
    Missing 'use strict' statement -->
    '$' was used before it was defined -->

    Those are your IDE's warnings. They are harmless in this case (e.g. your IDE simply isn't aware of Chrome or jQuery API) and not related to your problems. How to fix (or silence) them is IDE-dependent.

    Note that you should not rely on them only; after all, the browser is the final "consumer" of your code and has the final say. Take a look at the debugging tutorial for extensions to see how to access Chrome's console for your code.

    Now, for errors

    1. Using submit controls in Chrome extensions doesn't make sense; all they achieve is simply reloading the page. See this question as the canonical source, but TL;DR is to use input type button.

    2. You have a typo in your code:

      var amount = $('amount').val();
      

      This should have #amount. Sadly, jQuery simply returns undefined here instead of throwing a visible error.

    Next, the "why"

    Chrome extension popups do not survive being closed; it's not simply hidden until next time you open, it's opened freshly every time. Kind of like refreshing the page. So JS state does not survive - you can't keep data there and expect it to still be there next time.

    So you need some form of storage for persistence (unless you're fine with everything resetting when the popup closes). chrome.storage API is the "most native" choice - though in your case using sync is probably overkill, you can get away with local.

    It's important to understand the up- and downsides of various storage APIs. For example, sync can only store small amounts of data and can't be written to very frequently. Here's a good overview.