Backbone LocalStorage Models and Collections

856 views Asked by At

I am using Backbone and the Backbone LocalStorage plugin:

https://github.com/jeromegn/Backbone.localStorage

I seem to be having some trouble when it comes to saving Models into a collection, so I have decided to just use a collection to save my data, but now it seems as though I can't use the plugins methods to delete a record. Here is an example:

I add to local storage, where this is within my Backbone extended Collection

this.localStorage.create({id: nextPoint, date_stamped: new Date()});

Note, all the documentation I read did not mention the "localStorage" key which I was required to use here.

Next I tried to remove this key:

var previousRecord = this.localStorage.find({id:currentPoints});
this.localStorage.destroy(previousRecord);

Which returns the error:

TypeError: Cannot call method 'isNew' of null

Here is the Model

var PointModel = Backbone.Model.extend({
    localStorage: new Backbone.LocalStorage("Points"),
    defaults: {
        date_stamped: new Date()
    },
    /*initialize: function() {
        if(typeof this.id != 'number') {
            this.id = 11;
            this.date_stamped = new Date();
        }
    }*/
});

Here is the Collection

var PointsCollection = Backbone.Model.extend({
        model: PointModel,
        localStorage: new Backbone.LocalStorage("Points"),

        initialize: function() {
            this.pointsCard = this.createPointsCard();
        },

        // Public Methods
        getCurrentPoints: function() {
            return this.localStorage.records.length;
        }, 
        addPoint: function() {
            // get the current amount of points
            var currentPoints = this.getCurrentPoints(),
            nextPoint = currentPoints+1;
            if(nextPoint > _c.totalPoints) {
                return alert('Display error, reached limit');
            }
            // create 
            this.localStorage.create({id: nextPoint, date_stamped: new Date()});
        },
        removePoint: function() {
            // this may not work for the animation


            // maybe need to rethink this and add custom function to remove local
            // storage value
            var _this = this;
            // bit of a weird way to do this, but Backbone localStorage plugin didn't
            // seem to remove records very easily.
            var currentPoints = this.getCurrentPoints();
            // first clear all
            this.localStorage._clear();
            // then re add the original amount
            var range = _.range(1,currentPoints);
            _.each(range, function() {
                _this.addPoint()
            });


            // should work this way
            /*
            var currentPoints = this.localStorage.records.length,
            previousRecord = this.localStorage.find({id:currentPoints});
            this.localStorage.destroy(previousRecord);
            */
        },
        removeAllPoints: function() {
            this.localStorage._clear();
        },

        /*
            createPointsCard takes values from the config to
            make an array which has each point and its status for example:
            {
                id: [1-9],
                reward: string(rewardTitle) | false
                stamped: true | false
            }
        */
        createPointsCard: function() {
            var _this = this;
            // first create an array to hold the maximum number of points
            var range = _.range(1, _c.totalPoints+1),
            points = [];

            _.each(range, function(point) {
                var reward = _this._comparePointsNumberToReward(point);
                points[point] = {
                    id: point,
                    reward: reward,
                    stamped: true
                }
            });
            console.log(points)
            return points;
        },

        // Private Methods
        /*
            loop through each reward and then check if the current 
            point has a reward.
            return string(title) | false
        */
        _comparePointsNumberToReward: function(point) {
            var hasReward = false;
            _.each(_c.rewards, function(reward) {
                if(reward.pointsRequired === point) {
                    hasReward = reward.title;
                }
            });
            return hasReward
        }

    });

    return PointsCollection;
});
1

There are 1 answers

1
srquinn On BEST ANSWER

The Backbone.LocalStorage plugin replaces Backbone.sync either globally or on the collection's sync method with store.js, a x-browser implementation of LocalStorage. It also ONLY works on collections, not models. You shouldn't have to build any CRUD methods to interact with LocalStorage as the plugin uses the native save, fetch, etc.

With that said, I think your main bug comes from this: Collections should extend Backbone.Collection, not Backbone.Model

var PointsCollection = Backbone.Model.extend({});
// Should be
var PointsCollection = Backbone.Collection.extend({});

Because you are using models, the LocalStorage plugin isn't being used properly (it ONLY works on collections) and thus your need to drill into the prototype chain to gain access to the LocalStorage object.