Property of length undefined ? (

The coding of this simple budget app was progressing well until creating the new ID in the addItem method.

Chrome throws the errot “TypeError: Cannot read property ‘length’ of undefined
at Object.addItem” and Firefox throws “TypeError: data.allItems[type] is undefined”.

I cannot see what is wrong with data and data.allItems objects or the way I am creating the new ID?

// BUDGETT CONTROLLER
var budgetController = (function () {

    var Expense = function (id, description, value) {
        this.id = id;
        this.description = description;
        this.value = value;
    };

    var Income = function (id, description, value) {
        this.id = id;
        this.description = description;
        this.value = value;
    };

    var data = {
        allItems: {
            exp: [],
            inc: []
        },
        totals: {
            exp: 0,
            inc: 0
        }
    };

    return {
        addItem: function (type, des, val) {
            var newItem, ID;

            //[1 2 3 4 5], next ID = 6
            //[1 2 4 6 8], next ID = 9
            // ID = last ID + 1

            // Create new ID
            if (data.allItems[type].length > 0) {
                ID = data.allItems[type][data.allItems[type].length - 1].id + 1;
            } else {
                ID = 0;
            }

            // Create new item based on 'inc' or 'exp' type
            if (type === 'exp') {
                newItem = new Expense(ID, des, val);
            } else if (type === 'inc') {
                newItem = new Income(ID, des, val);
            }

            // Push it into our data structure
            data.allItems[type].push(newItem);

            // Return the new element
            return newItem;
        },

        // Test addItem function
        testing: function () {
            console.log(data);
        }
    };

})();

// UI CONTROLLER
var UIController = (function () {

    var DOMStrings = {
        inputType: '.add__type',
        inputDescription: '.add__description',
        inputValue: '.add__value',
        inputBtn: '.add__btn'
    }

    return {
        getInput: function () {
            return {
                type: document.querySelector(DOMStrings.inputType).value, // Will be either inc or exp
                description: document.querySelector(DOMStrings.inputDescription).value,
                value: document.querySelector(DOMStrings.inputValue).value
            };
        },
        getDOMStrings: function () {
            return DOMStrings;
        }
    };

})();

// GLOBAL APP CONTROLLER
var controller = (function (budgetCtrl, UICtrl) {

    var setupEventListerners = function () {
        var DOM = UIController.getDOMStrings();

        document.querySelector(DOM.inputBtn).addEventListener('click', ctrlAddItem);

        document.addEventListener('keypress', function (event) {
            if (event.keyCode === 13 || event.which === 13) {
                ctrlAddItem();
            }
        });
    };


    var ctrlAddItem = function () {
        var input, newItem;

        // 1. Get the field inpout data
        var input = UICtrl.getInput();

        // 2. Add the item to the budget controller
        var newItem = budgetCtrl.addItem(input.type, input.description, input.value);

        // 3. Add the item to the UI
        // 4. Calculate the budget
        // 5. Display the budget on the UI

    };

    return {
        init: function () {
            setupEventListerners();
        }
    }

})(budgetController, UIController);

controller.init();

This line is where that happens:

and it’s because an item index of type is not found, which must be either exp or inc.
Tracing it back we find that it comes from the following line:

So, you just need to confirm that the input field is being retrieved correctly, and has the appropriate type field.

2 Likes

Thank you Paul - all this time trying to find the problem in the javascript - the problem was in the HTML (had the option values as income and expense, not inc and exp!

I greatly appreciate the rapid response and insight.

2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.