0

In my TaskList class, I have a method called sortByWhenDue which is supposed to sort the Task objects in the _tasks attribute by the dates and times they are due (i.e. the Date object stored in the _whenDue attribute) from earliest to latest. However, when I try to use it, I get the error message Uncaught TypeError: Cannot read properties of undefined (reading '_whenDue'). Does anyone know what I should do about this? THanks.

class Task
{
    /**
     * @param {String} taskName a short description of the task
     * @param {String} category the category of the task
     * @param {Date} whenDue when the task is due
     */
    constructor(taskName, category, whenDue) {
        this._taskName = taskName;
        this._category = category;
        this._whenDue = whenDue;
    }

    get taskName() {
        return this._taskName;
    }

    get category() {
        return this._category;
    }

    get whenDue() {
        return this._whenDue;
    }

    set taskName(newTaskName) {
        if (typeof newTaskName === 'string') {
            this._taskName = newTaskName;
        }
    }

    set category(newCategory) {
        if (typeof newCategory === 'string') {
            this._category = newCategory;
        }
    }

    set whenDue(newWhenDue) {
        if (typeof newWhenDue === 'object') {
            this._whenDue = newWhenDue;
        }
    }

    fromData(data) {
        this._taskName = data._taskName;
        this._category = data._category;
        this._whenDue = data._whenDue;
    }
}

class TaskList
{
    constructor() {
        this._tasks = [];
    }

    get tasks() {
        return this._tasks;
    }

    addTask(task) {
        if (typeof(task) === 'object') {
            this._tasks.push(task);
        }
    }

    getTask(taskIndex) {
        return this._tasks[taskIndex];
    }

    fromData(data) {
        this._tasks = [];
        for (let i = 0; i < data._tasks.length; i++) {
            let tempName = data._tasks[i]._taskName;
            let tempCategory = data._tasks[i]._category;
            let tempWhenDue = new Date(data._tasks[i]._whenDue);
            let tempTask = new Task(tempName, tempCategory, tempWhenDue);
            this._tasks.push(tempTask);
        }
    }

    sortByWhenDue() {
        do { 
            let swapped = false;
            for (let i = 0; i < this._tasks.length; i++) {
                if (this._tasks[i]._whenDue > this._tasks[i+1]._whenDue) {
                    let temp = this._tasks[i+1];
                    this._tasks[i+1] = this._tasks[i];
                    this._tasks[i] = temp;
                    swapped = true;
                }
            }
        } while (swapped);
    }
}
2
  • 1
    Your loop continues while i < this._tasks.length is true. So if the length is 10 (say), on the last loop i is 9. So in if (this._tasks[i]._whenDue > this._tasks[i+1]._whenDue) {, i + 1 is 10 and this._tasks[10] is undefined because you've gone past the end of the array (an array with length = 10 has entries at indexes 0 through 9). Commented Nov 25, 2021 at 10:26
  • The best way to solve this sort of problem is to use the debugger built into your IDE and/or browser to step through the code and see the values of things as your logic is executed. Commented Nov 25, 2021 at 10:26

1 Answer 1

1

The this._tasks[i+1] is the problem. If you reach the end of for loop your code tries to access an index which does not exists. So undefined is returned and your code tries to get _whenDue from undefined.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.