0

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.

  • 1
    Where are you getting these errors - in IDE or browser? Also, you can store in variables if you don't need the values to persist after the popup is closed. – wOxxOm Aug 04 '17 at 11:52
  • @wOxxOm These errors are in the IDE. Although the **Total Spend** in the popup is also not updating. After I enter value in the input field and click submit, the **Total Spend** in the popup still remains 0 – jayanti hari Aug 04 '17 at 12:22
  • 2
    That's because the browser has no server so the page cannot be submitted: it simply reloads the page losing all data. Use a normal button and click event listener. As for IDE, you need to configure it like e.g. eslint has an environment for webextensions, or simply add `chrome` and `$` to globals. – wOxxOm Aug 04 '17 at 12:32
  • 2
    wOxxOm clearly identified the problem with the code, and I happen to remember it's a duplicate. For IDE errors, it's simply unaware of Chrome API / jQuery - and it's IDE-dependent how to make it aware. As to why use the Storage API - every time the popup is visually closed it's actually unloaded as a page (losing all JS state), and freshly loaded again next time it's shown, so if you need persistence you need _some_ storage. – Xan Aug 04 '17 at 12:35
  • @Xan So I tried changing to type: "button" like you had mentioned. But its still not working. – jayanti hari Aug 04 '17 at 13:00
  • You also have a typo `$("amount")` without `#`. Perhaps at this point its best to reopen, as there are multiple problems (and multiple questions in one - you should avoid it) – Xan Aug 04 '17 at 13:03

1 Answers1

1

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.

Xan
  • 74,770
  • 16
  • 179
  • 206
  • Meta-advice: for your next SO question, keep those in mind: 1) asking multiple separate questions in one isn't good for SO format, 2) you _must_ state what isn't working (not just error messages, but what's the behavior you're seeing vs expecting). – Xan Aug 04 '17 at 13:20
  • Thank you so much for all the explanation. This was really helpful :) – jayanti hari Aug 04 '17 at 13:39
  • You're welcome! I forgot the link to the debugging tutorial, edited it in now: https://developer.chrome.com/extensions/tut_debugging – Xan Aug 04 '17 at 13:41