0

I'm using the localStorage adapter with Backbone and have a Settings model that I store some basic settings on. In the init function, I create the settings model like this

window.onload = function() {

    window.settings = new Settings();

If the user decides to change the settings, I do this in an updateSettings function

settings.save({language: lang});

but rather than replace the settings in localStorage, it (as describes in the second answer on this question Saving a model in local storage) just creates a new storage item each time, so every time the settings change, a new instance gets stored. That means when I load the settings in my view after init, I have to set the language settings to the last item in the storage array

s[s.length - 1].language

with the whole function looking like this

$.when(products.fetch(), settings.fetch())

            .done(function(p, s){
            var l = s[s.length - 1] ? s[s.length - 1].language : 'en-us';                       
                settings.set({'language': l});   
                _this.render();

            });
    }

but this is very impractical because I don't want to store the whole history of the settings change in localstorage. As the first SO answer linked to said, I should use an id on the model. But if I assign an id in the application init like this

window.onload = function() {

    window.settings = new Settings({id: 1});

my application never renders, i.e. it never reaches the call to the render function in this code (I'm assuming it's because there's no records). Question: how can I call fetch here

  $.when(products.fetch(), settings.fetch())

                .done(function(p, s){
                var l = s[s.length - 1] ? s[s.length - 1].language : 'en-us';                       
                    settings.set({'language': l});   
                    _this.render();

                });
        }

so what I did was create the model in the application init without assigning the id

window.onload = function() {

    window.settings = new Settings();

Then when I call fetch on this model in the initializer in the view I assign the id like this, so that the fetch always returns

   $.when(products.fetch(), settings.fetch())

                .done(function(p, s){
                var l = s[s.length - 1] ? s[s.length - 1].language : 'en-us';                       
                    settings.set({'language': l, });
                    settings.set({id :1 });
                    settings.save();   
                    _this.render();

                });
        }

then when I change the settings in the update settings function like this

settings.save({language: lang});

However, if I change the settings and refresh the page a few times, it's clear that the whole history of settings is getting saved to localStorage

settings-1: "{"0":{"language":"de",","id":1},"language":"ja","id":1}"

(note, I'm actually saving more than just language settings)

Question: how can I set the id on a Backbone model so that localStorage updates the model in storage (rather than keeping a history of updates)?

Community
  • 1
  • 1
Leahcim
  • 40,649
  • 59
  • 195
  • 334

1 Answers1

1

Using the localStorage adapter with a singleton resource doesn't make much sense. I suggest to implement the sync method in your Settings Backbone model. Check the Backbone documentation, but in general the function signature is: function(method, model, options) Where the method can be: read, create, update, delete Just use the localStorage.getItem and localStorage.setItem, and something like this should work:


sync: function(method, model, options) {
  var key = 'settings';
  switch(method) {
    case 'read':
      try {
        data = JSON.parse(localStorage.readItem(key));
        model.set(data);
      } catch(e) {}      
      break;
    case 'update'
    case 'create'
      localStorage.setItem(key, JSON.stringify(model.toJSON()));
      break;
    case 'delete'
      localStorage.setItem(key, null)
  }
}

I didn't test it, but it should be something like this.

Roman
  • 13,100
  • 2
  • 47
  • 63
  • I think you missed the remark in the OP `(note, I'm actually saving more than just language settings)` so it's not really a singleton resource, however, if you change your answer, please add and don't take away what you already included because it would be valuable nonetheless – Leahcim Jun 21 '15 at 20:00