0

I am working on a Google Chrome extension which hides, moves, and otherwise alters elements of the current page, utilizing contentscripts to do so. I am working on a page which has a few elements I change, so I have a storage.sync value set for each. Due to the drastic nature of the changes each option effects, I have the toggles for each in my popup. I have tried to have each checkbox set the storage.sync value for the id of the checkbox to the boolean value of the checkbox using jQuery, specifically jQuery.click and jQuery.each. My popup's html is:

<html>
  <head>
    <title>Options</title>
    <script src="jquery-3.1.1.min.js"></script>
    <script src="popup.js"></script>
  </head>
  <body style="width: 400px">
    <h3>Settings</h3>
    <input class="option" id="opt1" type="checkbox">Option 1.</input><br>
    <input class="option" id="opt2" type="checkbox">Option 2.</input><br>
    <input class="option" id="opt3" type="checkbox">Option 3.</input>
    <button id="other">TBI</button>
  </body>
</html>

where 'jquery-3.1.1.min' is the minified jQuery source and popup.js is:

$(document).ready(function() {
    $('.option').each(function(index, elem) {
        chrome.storage.sync.get(elem.id, function (value) {
            elem.checked = value.fix;
        });
        elem.change(function() {
            chrome.storage.sync.set({this.id: this.checked);
        });
    });
});

I have also tried the replacing this with everything from elem to $(this)[0], as well as $(elem), but each time I get errors of a different source. In general, elem produces Uncaught SyntaxError: Unexpected token . and this produces Uncaught SyntaxError: Unexpected token this.

Why does this occur? How can I avoid this? I am primarily a python coder, so I expect I am misunderstanding the scope of each value or the meaning of this. What I don't understand is how that translates into Unexpected token errors. Thank you!

DW42
  • 101
  • 7
  • Possible duplicate of [How do I add a property to a JavaScript Object using a variable as the name?](http://stackoverflow.com/questions/695050/how-do-i-add-a-property-to-a-javascript-object-using-a-variable-as-the-name) – Makyen Mar 12 '17 at 02:46
  • No, this refers to a different question. `this` and a variable are fundamentally different concepts and have different semantics. This questions could be named 'How do I use properties of `this` as an object property names?' to show its difference from the question you referenced. – DW42 Mar 12 '17 at 02:57
  • `this` is just a variable. At that point in your code, it happens to point to an Object which has a property `id`. There is no difference between `this` and any other variable, other than it gets automatically set to particular values in some circumstances. – Makyen Mar 12 '17 at 03:04
  • Note that there are other things that are similar. For example, `window` and `document` are also just variables that happen to point to Objects. In some JavaScript environments those variables are not set, you have to set them yourself, if you want to use them. – Makyen Mar 12 '17 at 03:10
  • Yes, but this deals with the semantics of `this` in particular as well as jQuery, overlapping scopes, and other complex concepts that go beyond just setting a name determined by a variable, even if that was the eventual solution. – DW42 Mar 12 '17 at 03:17
  • There's also a asynchronous code issue, which is 2 more duplicates: [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](http://stackoverflow.com/q/23667086) & [How do I return the response from an asynchronous call?](http://stackoverflow.com/q/14220321). So, yes, there are really three duplicates, but I only get to directly specify one. There is also the missing `}` typo. While other portions of your code may be more complex, for the code in the question, that was about it. However, your question is *specifically* about the syntax error. – Makyen Mar 12 '17 at 03:40
  • After re-review of the two questions, I think it's up to interpretation. On the one hand, it does deal with similar issues as other questions, but on the other, it does involve more complex issues. It's rather subjective. – DW42 Mar 12 '17 at 03:54

1 Answers1

1
  1. this.id is an invalid key in an object literal.
    You can use {[this.id]: this.checked} if you're okay with ES2015 requirement.
    Or use a temporary object variable: var o = {}; o[this.id] = this.checked;
  2. Typo: missing } in the object literal.
  3. chrome.storage is asynchronous so elem.change is attached before the value is actually retrieved, which might be not what you really want. However, in this case it's not a big deal: you just write the same value back to chrome.storage.
  4. It's better to read all values in one go by providing an array of keys:

    chrome.storage.sync.get(
        $('.option').map((i, el) => el.id),
        data => {
            $.each(data, (id, value) => $(`#${id}`)[0].checked = value);
            $('.option').change(function() {
                chrome.storage.sync.set({[this.id]: this.checked});
            });
        }
    );
    
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • Thank you for the response! I think that while I grow more comfortable with jQuery and javascript in general I will stick to `[this]`. – DW42 Mar 12 '17 at 00:34