Struggling to make the controller karma test pass

I am currently working on developing a "To Do list" using angular js. My goal is to allow users to click on a checkbox to mark tasks as completed after they have been finished. While the functionality works fine in the index.html file, I am struggling to pass the test itself.

Below is the test scenario:

describe('ToDoListController', function() {
  beforeEach(module('ToDoList'));

  var ctrl;

  beforeEach(inject(function($controller) {
    ctrl = $controller('ToDoListController');
  }));

  it('initialises with an empty list and term', function() {
    expect(ctrl.listDisplay).toEqual([]);
    expect(ctrl.taskTerm).toBeUndefined();
  });

  describe('when viewing the to do list', function(){

    it('displays list items', function() {
      ctrl.taskTerm = "hello";
      ctrl.addTask();
      expect(ctrl.listDisplay[0].task).toBe("hello");
    });

    it('is completed when clicked', function() {
      ctrl.taskTerm = "hello";
      ctrl.addTask();
      ctrl.isCompleted("hello");
      expect(ctrl.listDisplay[0].completed).toBe(true)
    });

  });
});

Here is the snippet from my controller:

toDoList.controller('ToDoListController', [function() {

  var self = this;
  self.listDisplay = []

  self.addTask = function() {
    self.listDisplay.push({task: self.taskTerm, completed: false})
  };

  self.isCompleted = function(item) {
    var i = self.listDisplay.indexOf(item)
    self.listDisplay[i].completed = true
  }
}]);

The error message that I am encountering reads as follows:

TypeError: Cannot set property 'completed' of undefined
    at self.isCompleted (/Users/edobrien/Documents/Projects/todo_challenge/js/toDoListController.js:13:35)
    at Object.<anonymous> (/Users/edobrien/Documents/Projects/todo_challenge/test/toDoListController.spec.js:26:12)

The issue appears to be stemming from the line "ctrl.isCompleted("hello");"

I would greatly appreciate any guidance or assistance you may have to offer!

Answer №1

Your controller needs to make a crucial adjustment in the isCompleted method. The list being utilized is an array of objects, not strings:

self.addTask = function() {
    self.listDisplay.push({task: self.taskTerm, completed: false})
};

If you input "hello" as the taskTerm, it will create an object like this within the array:

{task: "hello", completed: false}

Therefore, attempting to locate "hello" using indexOf("hello") will always result in -1 because

"hello" != {task: "hello", completed: false}

To solve this issue, alter how you search for an object in the array:

self.isCompleted = function(item) {
    var completed=false;
    self.listDisplay.forEach(function (value,index) {
        if (value.task ==item) {
            completed=value.completed;
        }
    });
    return completed;
};

UPDATE: It appears there was a misunderstanding in interpreting your code. Typically, isCompleted indicates a method that checks completion status. However, your method actually sets completion status. In such cases, methods are commonly named as setCompleted.

Hence, the method should resemble this:

self.setCompleted = function(item) {
    self.listDisplay.forEach(function (obj,index) {
        if (obj.task == item) {
            obj.completed=true; //setting it as completed
        }
    });
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Passing array map data to another screen in React Native

Greetings! I successfully created an array map to showcase specific data from my API. Now, I am faced with the challenge of TRANSFERRING THIS DATA TO ANOTHER SCREEN. My current dilemma lies in the fact that the displayed data is generated using ARRAY MAP, ...

Executing a post request asynchronously and storing the retrieved data into a variable

Currently, I am in the process of learning AngularJS and attempting to upgrade my current method of fetching data from a web service and dynamically assigning it to a variable that is binded using ng-repeat. My main objective is to implement an asynchronou ...

Using the JavaScript selectionchange event to target a specific element exclusively

I am looking for a way to incorporate a JavaScript selectionchange event on a specific div element. The goal is to display a highlighter box when the user selects text from the DOM. I was able to achieve this functionality for web using an onmouseup event, ...

The Bootstrap validator triggers the form submission only after the second click

When I click on the submit button, I am attempting to submit a form that has its default action prevented and first checks a condition before proceeding. Below is the code snippet: $('#payment-form').bootstrapValidator({ live: 'dis ...

Comparison between bo-html and bo-text

As I was going through the documentation for the bindonce directive, a question popped into my head regarding the distinction between bo-html and bo-text. bo-html: This evaluates "markup" and displays it as HTML within the element. bo-text: ...

Traversing a hierarchical JSON structure reminiscent of a tree object

I am working with a complex object structure, var cObj = { name: 'Object1', oNumbers: 3, leaf: [ { name: 'Inner Object 1', oNumbers: 4, leaf: [] }, { name: 'Inner Object 2', oN ...

Implement a logging system to track and record data from both incoming requests and outgoing responses on a server powered by Express and Node.js

Is there a way for my server to log the response and request data when posting to another server? Thank you. const request = require('request'); postToIotPlatform = function postToIotPlatform(req, res, next) { var formData = JSON.stringify( ...

Exploring Pyspark: Implementing the best approach to handle nested arrays in JSON data as "column-row" or "key-value" format

I have a unique json file structured similarly to the example below. My goal is to extract the information and display it in a table format with all the attributes of the individual. { "person":[ [ "name", "Jane ...

Incomplete Json information

As I embark on my journey to learn Javascript and work on building an application simultaneously, I can't help but feel optimistic about the learning process. To guide me through this venture, I've turned to the teachings of Alex MacCaw in his bo ...

Transmitting form information to a nested page within a div container

This is my fourth attempt to seek an answer to this question, as I've faced downvotes in previous attempts. So here we go again. I am trying to send data from a hidden input within a form using ajax. The value of the hidden input is generated by a php ...

Why is it necessary to decode JSON stringified objects in Vue props?

When passing a stringifyed object via props to a component, it seems like there is an issue with the data transformation. <my-component :filter="stringobject" ></my-component> stringobject = "{"search_text":"(ciCl ...

Issue with Angular routing failing to function properly on Chrome

I've been experimenting with AngularJS and watching Dan Wahlin's tutorial on YouTube, but I'm having trouble getting the routing to work properly in Chrome or IE. It seems to be working fine in Firefox, but in other browsers, it just shows a ...

Is it possible to update a module on an end user's device without using npm or node.js?

Currently, I am working on developing an electron application along with a module that it uses. My main concern is ensuring that this module gets updated on the end user's machine whenever there is a new version available, even if they do not have NPM ...

What is the appropriate response to send to the user in a web application?

I am currently developing a web application that utilizes AngularJS for the frontend, a REST API, and MongoDB as the backend, all powered by Node.js. Background to the challenge: One key requirement is to authenticate users using token-based authenticati ...

Is AngularJS not able to effectively manage the button type "reset"?

I currently have the following code snippet: <form name="editor"> <h2>Create/Update</h2> {{ editor.title.$error.required }} <div ng-class="{ 'has-error': editor.title.$invalid && editor.title.$dirty, &apo ...

Ways to implement debounce in handling onChange events for input fields in React

I've been attempting to implement debounce functionality in my React app without relying on external libraries like lodash or third-party node modules. I've tried various solutions found online, but none have worked for me. Essentially, in the h ...

all-encompassing ajax call method with jquery

Is there a universal function for calling ajax requests globally? For example, instead of writing the same code multiple times: $.ajax({ url: some_url_address, type: 'post', data: $('#form').serialize(), dataType: &apos ...

What causes the `d-none` class to toggle on and off repeatedly when the distance between two div elements is less than 10 during window resizing?

My primary objective is to display or hide the icon based on the width of the right container and the rightButtonGroupWrapper. If the difference between these widths falls below 10, the icons should be shown, otherwise hidden. However, I'm facing an i ...

Tips for using jQuery to identify the most recently modified row in an HTML table

Is there a way to identify the most recently modified (either newly added or changed) row in an HTML table? ...

DOM doesn't reflect changes to nested object when component prop is updated

I have a complex object structured in a multidimensional way that appears as follows: obj: { 1: { 'a' => [ [] ], 'b' => [ [] ] }, 2: { 'x' => [ [], [] ] } } This object is located in the r ...