Struggling to integrate Karma and Jasmine into my Angular controller setup

After numerous attempts and hours of troubleshooting, I am still unable to successfully integrate Karma with my Angular controller. No matter what I try, the same error persists even when removing expectGET() calls - as soon as $http.flush(); is called.

An error message stating: TypeError: Cannot set property 'totalBeforeDiscounts' of undefined.

The code snippet for my controller is shown below:</p>

<pre><code>var quotePadControllers = angular.module('quotePadControllers', []);

quotePadControllers.controller('QuotesController', ['$scope', '$http', '$q', function($scope, $http, $q){

var blankAddon;

// Initialization and setting default values
var ajaxGetAddOns = $http.get('/?ajax=dbase&where=aons'),
    ajaxGetFrames = $http.get('/?ajax=dbase&where=fcats');

$q.all([ajaxGetAddOns, ajaxGetFrames]).then(function(results){

    $scope.addons = results[0].data;
    $scope.frames = results[1].data;

    $scope.pairs = [
        {
            "frames" : angular.copy($scope.frames),
            "addons" : angular.copy($scope.addons),
        }
    ];
});

// Function for adding a new pair
$scope.addPair = function()
{

    $scope.pairs.push({
            "frames" : angular.copy($scope.frames),
            "addons" : angular.copy($scope.addons)
    });
};

// Function for removing a pair
$scope.removePair = function()
{
    if ( $scope.pairs.length > 1 ) 
    {
        $scope.pairs.pop();
    }
};


// Continuously updating subtotal and total
$scope.$watch('pairs', function(pairs) {
    var totalBeforeDiscounts = 0; 
    angular.forEach(pairs, function(pair) {
        var subTotal = 0;
        angular.forEach(pair.addons, function(addon) {
            subTotal += addon.added ? addon.price : 0;
        });

        subTotal += pair.currentFrame !== undefined ? pair.currentFrame.price : 0;
        pair.subTotal = subTotal;
        totalBeforeDiscounts += subTotal;
    });
    pairs.totalBeforeDiscounts = totalBeforeDiscounts;
}, true);
}]);

The test code snippet is as follows:

describe('QuotesController', function()
{
beforeEach(module('quotePadApp'));

var ctrl, $scope, $http, frameCatsHandler, addOnsHandler, createController;


// Setting up tests
beforeEach(inject(function($controller, $rootScope, $httpBackend, _$q_) {

    $scope = $rootScope.$new();
    $http = $httpBackend;

    frameCatsResponse = [{"id":145,"price":25,"brand":"mybrand"},
                         {"id":147,"price":45,"brand":"mybrand"},
                         {"id":148,"price":69,"brand":"mybrand"}]; 

    addOnsHandler = [{"id":1,"name":"addon1","price":30,"includeIn241":0,"description":null},
                     {"id":2,"name":"addon2","price":60,"includeIn241":0,"description":null}];              

    frameCatsHandler = $http.when('GET', '/?ajax=dbase&where=fcats').respond(frameCatsResponse);
    addOnsHandler = $http.when('GET', '/?ajax=dbase&where=aons').respond(addOnsHandler);

    createController = function()
    {
        return $controller('QuotesController', {'$scope' : $scope });
    };
}));

it('Should request frame cats and addons from the database', function()
{
    $http.expectGET('/?ajax=dbase&where=aons');
    $http.expectGET('/?ajax=dbase&where=fcats');
    createController();
    $http.flush();
});
});

Answer â„–1

The reason for this issue is the presence of a watch statement in your controller that attempts to assign a totalBeforeDiscounts property on $scope.pairs.

$scope.$watch('pairs', function(pairs) {
    // ...
    pairs.totalBeforeDiscounts = totalBeforeDiscounts;
}, true);

During your tests, when you initialize the controller and then invoke $http.flush(), it triggers a $digest cycle which activates all watchers.

createController();
$http.flush();

The watch handler mentioned above runs before $scope.pairs has any value available. As a result, the pairs argument passed to the watch handler is undefined, leading to an error.

According to the documentation:

Once a watcher is set up with the scope, the listener function is executed asynchronously (via $evalAsync) to start the watcher. In certain cases, this behavior may not be ideal because the listener is triggered even when the watchExpression remains unchanged. To identify this situation within the listener function, you can compare the newVal and oldVal. If these two values are identical (===), then the listener was fired due to initialization. https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

Additionally, in the rest of your code, $scope.pairs is treated as an array; however, in the watch statement, you are trying to modify a property like totalBeforeDiscounts, which seems inaccurate.

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

Action creator incomplete when route changes

In my React-Redux application, there is an action creator that needs to make 4 server calls. The first three calls are asynchronous and the fourth call depends on the response of the third call. However, if a user changes the route before the response of t ...

Tips for transferring a prop from a parent component to a child in Vue.js

I have a main component named Stepper that includes a child component called ShortSummary. I am attempting to pass a property from Stepper to ShortSummary by clicking on a radiobutton, but it is not working! Here's my setup. This is the code for Stepp ...

Comparison: Chrome extension - utilizing default pop-up vs injecting a div directly into the page

I find myself perplexed by the common practices used in popular Chrome extensions. I am currently working on creating my own Chrome extension and after completing a basic tutorial, I have set up a default popup page that appears when clicking the extensi ...

What should I do to resolve the issue of the function if ($(window).width() < 768) {} not functioning properly upon resizing the browser?

I am working on a functionality where the navigation bar items will toggle hidden or shown only when the browser width is less than 768px and an element with the class "navlogo" is clicked. I have included my code below for reference. if ($(window).width( ...

Does the awaitMessages filter not execute the .then function?

I am currently implementing a direct message prompt in my bot, where the player must respond before the bot proceeds with further questions. I have set up a filter to prevent the bot from detecting and acknowledging its own message. However, for some reaso ...

Initialization of Arrays with Default Values

I have taken on the task of converting a C++ program into JavaScript. In C++, when creating a dynamic array of type float/double, the entries are automatically initialized to 0.0; there is no need for explicit initialization. For example, a 1-D vector of ...

Personalize the appearance of your stackLabels in Highcharts with dynamic customization options

I recently created a bar graph using Highcharts. You can check it out here: http://jsfiddle.net/v1rbz41q/3/ Here's the code snippet I used: chartw.yAxis [0] .options.stackLabels.formatter = function () {              return "werfdc";   ...

Utilizing ReactJS for Web Development with Enhanced Data Insights from Google

Utilizing Google Analytics and various tools, I've encountered an issue with the development of ReactJS. My goal was to collect analytics data from my website by using react-helmet to dynamically change the title and the HTML lang parameter based on t ...

Having trouble with Semantic UI Modal onShow / onVisible functionality?

Seeking assistance with resizing an embedded google map in a Semantic UI modal after it is shown. After numerous attempts, I have narrowed down the issue to receiving callbacks when the modal becomes visible. Unfortunately, the onShow or onVisible functio ...

Combine a segment from two arrays into a single array

I have two arrays and I want to merge them into one while extracting only certain elements... I am using axios with vueJS. (9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] 0: Nombredejours: 1.5 Task: {id: "52edcb0e-450f-4de7-b70d-b63e0 ...

Can MooTools be used for asynchronous file uploads?

Currently, I am working on file uploading using asp.net: <asp:FileUpload ID="Upload" runat="server" /> <!-- HTML --> Upload.PostedFile.SaveAs(physicalPath + "newAvatarTemp.png"); // codebehind However, I find it frustrating when pages need to ...

What strategies can be implemented to maximize memory and CPU efficiency in NodeJS and Express?

My Node app, running on Express, utilizes a web scraping tool to gather and analyze data. While NodeJS is praised for its scalability and ability to handle numerous concurrent connections, I've noticed some difficulties when operating a web scraper t ...

What is the best method for searching through all keys of an object?

Multiple documents contain a key called userId, where this key is always an object: { "id": { "$oid": "22fc6b11a0ff111d598b114f" }, "userId": { "KEY1" : ["..."], "KEY2" : ["..."], ...

Issues arise when using the Jquery addClass method as it may not

Recently delving into Jquery, I encountered an issue. My goal is to click on the send button and have the input's border turn red. Here's the HTML code: <input type="text" placeholder="Put your name" id="name"/> <input type="submit" va ...

Managing the ajax response to showcase a button within datatables

Here is my current datatable structure: <table id="list" class="display" width="100%" > <thead> <tr> <th>Title</th> <th>Description</th> <th>delete</th> ...

Conceal the content inside a DIV based on the character length of a

I'm having trouble trying to hide content in a div based on the length of a textbox value when a key is pressed. The current solution isn't working as expected. Is the backspace key not considered a keypress event? If you take a look at the code ...

After completing my code, I noticed some warnings present. What steps can I take to address and fix them?

I was assigned a task by my teacher Upon completion, I received 2 warnings which my teacher does not appreciate Can anyone assist me in resolving these warnings? I attempted to fix the 2nd error by: function (obj) { or obj => However, the warnin ...

Having trouble initiating a "curl:localhost:3000" connection, receiving a URI Error message

Recently delving into the realm of node js, I have embarked on a journey to start up a server and experiment with an app designed to trim URLs. However, I find myself at an impasse. Environment: Windows Text Editor: VSCode Below is my code for index.js ...

Identifying CMYK Images Through Javascript Feature Detection

Many are aware that IE8 does not support CMYK JPG images, as it fails to render them at all. This post discusses the issue further: , among others. My inquiry is as follows: Is there a method to detect from JavaScript, akin to Modernizr, whether a browse ...

The WebSocket connection to '...' was unsuccessful due to an invalid frame header

I currently utilize express and socket.io for my project. The node server is up and running on 127.0.0.1:3000, and I have successfully established a connection. var socket = io.connect('http://127.0.0.1:3000', {query: 'id=' + user.id} ...