Search code examples
javascriptbackbone.jsbackbone-local-storage

I'm unable to delete an existing localstorage value in backbone.js


As a personal project, I'm working on a food calculator in backbone.js. I'm storing the food entries via backbone.localstorage.js. I've got most of it working fine. The only issue that I'm having is after I save my items and I hit refresh, I'm unable to delete the items. If I add an item, I can delete it directly after I delete it.

Here's my function where I initialize everything:

initialize: function () {        
        this.model = new SearchList();
        this.foods = new AllFoods();
        this.journal = new FoodJournalDay();
        this.prepCollection = _.debounce(this.prepCollection, 1000);
        this.$totalcal = $('#totalcal span');
        this.$totalcalfat = $('#totalcalfat span');
        this.$totalprotein = $('#totalprotein span');
        this.$totalcarb = $('#totalcarb span');
        this.$totalfat = $('#totalfat span');
        this.$totalsugar = $('#totalsugar span');
        this.$totalsodium = $('#totalsodium span');
        this.$totalpotassium = $('#totalpotassium span');
        this.$list = $('#listing');
        this.$breakfast = $('#breakfast');
        this.$lunch = $('#lunch');
        this.$dinner = $('#dinner');
        this.$snack = $('#snack');
        this.$tracked = $('#tracked');

        this.listenTo(this.journal, 'all', _.debounce(this.render, 0));
        this.model.on('destroy', this.remove, this);
        this.listenTo(this.journal, 'destroy', this.renderfoods);        
        this.foods.fetch();        

        var myNotes = new FoodJournalDay();
        myNotes.fetch();

        myNotes.models.forEach(function(model){

            var mealli = model.get("html");

            var calcount = parseFloat(model.get("calories"));
            var proteincount = parseFloat(model.get("protein"));
            var carbscount = parseFloat(model.get("carbs"));
            var fatcount = parseFloat(model.get("fat"));
            var sugarcount = parseFloat(model.get("sugar"));

            totalcal += calcount;
            totalprotein += proteincount;
            totalcarb += carbscount;
            totalfat += fatcount;
            totalsugar += sugarcount;

            switch (model.get("meal")) {

                case 'Breakfast':
                    $('#breakfast').append(mealli);
                    break;
                case 'Lunch':
                        $('#lunch').append(mealli);
                    break;
                case 'Dinner':
                        $('#dinner').append(mealli);
                    break;
                case 'Snack':
                    $('#snack').append(mealli);
                    break;
                default:
                    //alert("Please select a meal!");
            }


            $('#totalcal span').html(totalcal);
            $('#totalprotein span').html(totalprotein);
            $('#totalcarb span').html(totalcarb);
            $('#totalfat span').html(totalfat);
            $('#totalsugar span').html(totalsugar);
        });
    },

Here is my delete function:

destroy: function (e) {
        var $li = $(e.currentTarget).closest('li');
        var id = $li.attr('data-id');
        $li.remove();

        console.log("li id: " + id);
        console.log(this.journal);

        this.journal.get(id).destroy();
    },

I've made a fiddle of what I'm working on: https://jsfiddle.net/brettdavis4/ynm2sse9/2/

Thanks!


Solution

  • i'm back for round 2 :p.

    You added 2 identical collections to the view. You should stick with one.

    Originally you had this.journal = new FoodJournalDay(); as your collection. And in my previous answer this.journal.get(id).destroy(); successfully deleted the item. However in your new code you've created another collection var myNotes = new FoodJournalDay();. This is fairly pointless because you already have a FoodJournalDay() collection assigned to this.journal.

    You populated myNotes with a fetch(), thus you left this.journal empty. Since this.journal is doing the deletion, it tries to find the model with the id this.journal.get(id). This returns undefined since there is no model with that id, in fact there are no models at all in the collection. That's why you get the error msg Cannot read property 'destroy' of undefined.

    When something isn't working, i suggest following the flow of the program and placing console.log() statements everywhere checking the contents of your collection, models, and see if you can pick up any unexpected behavior.

    https://jsfiddle.net/guanzo/1mq7mdm1/

    I replaced

    var myNotes = new FoodJournalDay();
    myNotes.fetch();
    
    myNotes.models.forEach(function(model){
    

    with this. Using the original collection.

    this.journal.fetch();
    this.journal.models.forEach(function(model){