Error: While testing an AngularJS controller with Karma, there was an issue accessing the property 'then' of an undefined variable

I'm currently working on writing unit tests for a controller that receives a promise from a service. However, when using Jasmine, I encounter the following error:

TypeError: Cannot read property 'then' of undefined

Within the controller, I am trying to use .then() on the promise returned by the service.

Can anyone provide assistance? I must be overlooking something obvious.

Here is a link to the plunk: http://plnkr.co/edit/vJOopys7pWTrTQ2vLgXS?p=preview

'use strict';

describe('Language controller', function() {
    var scope, translationService, createController;

    beforeEach(function() {
        var mockTranslationService = {};
        module('dictApp', function($provide) {
            $provide.value('translationService', mockTranslationService);
        });

        inject(function($q) {
            mockTranslationService.languages = [
                {
                    name: 'slovak'
                },
                {
                    name: 'czech'
                }
            ];

            mockTranslationService.languagesWithWords = [{
                name: 'slovak',
                words: [{
                    key: 'Car',
                    translation: 'Auto',
                    createdOn: 0
                }, {
                    key: 'Flower',
                    translation: 'Kvet',
                    createdOn: 0
                }]
            }, {
                name: 'czech',
                words: {
                    key: 'Plaza',
                    translation: 'Namesti',
                    createdOn: 0
                }
            }];

            mockTranslationService.getLanguages = function() {
                var deferred = $q.defer();

                deferred.resolve(this.languages);
                return deferred.promise;
            };
        });
    });

    beforeEach(inject(function($controller, $rootScope, _translationService_) {
        scope = $rootScope.$new();
        translationService = _translationService_;
        createController = function () {
            return $controller('LanguageCtrl',
                    {$scope: scope, translationService: translationService});
        };
        scope.$digest();
    }));

    it('should retrieve the language array', function() {
        spyOn(translationService, 'getLanguages');
        createController();
        expect(translationService.getLanguages).toHaveBeenCalled();
    });
});

And here is the controller code:

   dictControllers.controller('LanguageCtrl', ['$scope', 'translationService', function($scope, translationService){


        $scope.getLanguages = function() {
            translationService.getLanguages().then(function(){
                $scope.languages = translationService.languages;
            });
        };

        $scope.getLanguages();

        $scope.getWords = function(language) {
            translationService.getWords(language);
        };


        $scope.newWord = {};

        $scope.addWord = function(language) {
            translationService.addWord($scope.newWord, language);
            $scope.newWord = {};
            };

    }]);

Answer №1

For a more efficient approach, try using

spyOn(mockTranslationService, 'getLanguages').and.returnValue(deferred.promise);
instead. Resolving the promise after the call to getLocations() rather than before its return is also recommended. Don't forget to verify the languages as well.

inject(function($q) {
    deferred = $q.defer();

    mockTranslationService.languages =  [
        {
            name: 'slovak'
        },
        {
            name: 'czech'
        }
    ];

    mockTranslationService.languagesWithWords = [{
        name: 'slovak',
        words: [{
            key: 'Car',
            translation: 'Auto',
            createdOn: 0
        }, {
            key: 'Flower',
            translation: 'Kvet',
            createdOn: 0
        }]
    }, {
        name: 'czech',
        words: {
            key: 'Plaza',
            translation: 'Namesti',
            createdOn: 0
        }
    }];

    mockTranslationService.getLanguages = function () {
    };

    spyOn(mockTranslationService, 'getLanguages').and.returnValue(deferred.promise);

});

it('should retrieve the language array', function() {
    createController();

    deferred.resolve();
    scope.$digest();

    expect(translationService.getLanguages).toHaveBeenCalled();
    expect(scope.languages).toEqual(translationService.languages);
});

Plunkr

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

What is the best way to interact with my component in React?

As a newcomer to Reactjs, I have a question regarding my current setup: The components in my project include navComponent.js, stackComponent.js, and nav.js I am trying to pass data from stackComponent.js to navComponent.js so that the nav.js data can be ...

Sending information across React context

I've encountered a challenge when trying to transfer data from one context to another in React. The job data I receive from a SignalR connection needs to be passed to a specific job context, but I'm unsure of the best approach for achieving this. ...

Is there a way to determine the color of an element when it is in a hover state?

I recently started using the Chosen plugin and noticed that the color for the :hover on the <li> elements is a bright blue. I want to change it to a bold red color instead. https://i.stack.imgur.com/mcdHY.png After inspecting it with the Chrome too ...

Utilizing Flask's get and post methods in conjunction with AJAX integration

I am in the process of developing a food calorie web application and would like to extract data from a MongoDB database into an HTML table. This is my python code: from flask import Flask from flask import request import requests from wtforms import Form ...

Automate the process of modifying specific data in tables through Javascript

I've been attempting to replicate the appearance of a stock-exchange board, but I'm encountering difficulties in updating text automatically without interrupting another. My attempts so far: var textPositive = ["2.0%", "1.7%" ...

Dealing with errors in multer and express-validator aspects

Is there a way to validate a form that includes an image using multer and other fields with express-validator? I keep encountering an undefined error (req.validationError) in the post route. Any suggestions on how to resolve this issue? server.js const e ...

Express Js: Implementing Dynamic Data Loading on Scroll

We are currently facing an issue where the dynamic data from Mongo db is loading all at once instead of through scrolling. Our objective is to have the data load progressively as we scroll, all on one single page. // We attempted using Lazy loading carous ...

What is the best way to split an input field into distinct fields for display on the screen?

Take a look at this image: https://i.stack.imgur.com/LoVqe.png I am interested in creating a design similar to the one shown in the image, where a 4 digit one-time password (OTP) is entered by the user. Currently, I have achieved this by using 4 separate ...

Eliminate redundant code within the reducer function in a React application

I have recurring code in reducers where only the property name changes. How can I refactor this to eliminate redundancy? const reducer = (state, action) => { switch (action.type) { case ADD_ITEM: { if (state.toggleCost) { let l ...

Is it possible to use regex to replace all content between two dashes, including any new

I have a specific set of dashed markers that I am looking to update based on the content of $("#AddInfo"). If the field is not empty, I want to replace everything between the markers. Conversely, if $("#AddInfo") is empty, I need to remove all text betwe ...

Leveraging the power of React Native with embedded RapidAPI functionality in the source

I had previously used the following code to retrieve a JSON file containing personal data in my React Native source code: async componentDidMount() { try { const response = await fetch('mydomain.org/personaldata.json'); const responseJson ...

Adjusting the inline styling of an element to enhance its appearance

Currently, the code is functioning as follows: var ball = document.getElementById('ball'); //some code let bml = parseInt(ball.style.marginLeft,10); //if *conditional statement* is true, do: ball.setAttribute("style","margin-left:& ...

Obtain a particular value from a JSON file using JavaScript

My JSON file, named json.json, contains the following data: {"name1":"Hallo","name2":"Defy","name3":"Carm","name4":"Disney"} To read this file, I am using the following script: <script type='text/javascript'> $(window).load(function(){ $ ...

Stop Users from Inputting Decimal Numbers with JavaScript

Just starting out with Java Script and looking to restrict users from entering decimals in a field using JavaScript. I attempted this approach but encountered the following error. Syntax error on token "_$tag____________", invalid AssignmentOperator < ...

Proper approach for mapping JSON data to a table using the Fetch API in a React.js application

Struggling to map some elements of JSON to a Table in Customers.jsx, but can't seem to figure out the correct way. How do I properly insert my Fetch Method into Customers.jsx? Specifically managing the renderBody part and the bodyData={/The JsonData/} ...

What is the process for retrieving the value of the inputText field using document.getElementById in adf?

I need assistance in obtaining the value of an inputText field using document.getElementById within a javascript function in ADF. I have provided my JavaScript function below but unfortunately, instead of the expected value, I am receiving "undefined" in ...

What seems to be causing the malfunction in this ranking function?

I created a custom function to retrieve the top five users from a JSON database. Below is the code snippet: var users = []; Object.keys(database).forEach(user => { if (!users[0]) { users[0] = user } else { var checked = false; for (let ...

JQuery Code Issue: DataTable Pagination Buttons and Records Information not Displaying

When using the Datatable plugin for pagination, I am encountering an issue where the pagination buttons and records information ("Showing X out of Y Records") are not displaying. Despite correctly fetching the records when selecting the page size from the ...

Can a console application be created using AngularJS technology?

My task involves creating a console application that interacts with an API, modifies the data, and displays it on the console when a specific command is run. Is it feasible to achieve this using AngularJS? If not, what about utilizing Angular6 instead? To ...

What is the process for changing CORS origins while the NodeJS server is active?

Currently, I am in the process of modifying the CORS origins while the NodeJS server is operational. My main goal is to replace the existing CORS configuration when a specific user action triggers an update. In my attempt to achieve this, I experimented w ...