What are the steps I should take to resolve the unit test problem specific to my situation?

I have been encountering an issue while trying to unit test two functions, as I keep receiving an error indicating an undefined object.

This is my controller:

vm = this;
//always fire first in the app
vm.getCompany = function() {
    api.getCompany(function(res){        
        //do stuff
    })
}

//always fire second in the app
vm.getEmployee = function() {
    api.getEmployee(function(res){
        //do stuff
    })
}

This is my API service:

var company;

function getCompany() {
   var company;
   var q = $q.defer();
   var url = ‘something.com’;

  anotherApi.getCompany(url).then(function(comp){
          company = comp;
          q.resolve(company)
    })
}

function getEmployee = function() {
    var name = company.name
    var url = ‘something.com/’ + name;
    var q = $q.defer();
    anotherApi.getEmployee(url).then(function(employee){
          q.resolve(employee)
    })
}

Here is my unit test:

beforeEach(function(){
   module(‘myApp);
        inject(function ($injector) {
            $controller = $injector.get('$controller');
            $rootScope = $injector.get('$rootScope');
            $scope = $rootScope.$new();
            $httpBackend = $injector.get('$httpBackend');
            api = $injector.get('api');
        });

         vm = $controller'myCtrl', {
            $scope : $scope
        });

})

describe (‘test’, function(){
    it(‘should get company’, function(){
         vm.getCompany();
         $httpBackend.flush();
         // stuff and works
    })
    it(‘should get Employee’, function(){
        vm.getEmployee()
        $httpBackend.flush();
        //getting error says 
        //'undefined' is not an object (evaluating 'company.name’)
    })
})

In the getEmployee function of the service, I consistently encounter the error message:

'undefined' is not an object (evaluating 'company.name’)
.

I have attempted multiple solutions without success. Any assistance would be greatly appreciated. Thank you!

Answer №1

When calling getEmployee before getCompany, it is important to check if the company is null before trying to use it. Consider storing the company in a property that can be accessed within your service. This property can be prefixed with an underscore to distinguish it from the public api:

{
    _company: null,
    getCompany: function() {
        var self = this;
        var url = '...';
        return $http.get(url).then(function(comp){
            self._company = comp;
            return self._company;
        });
    },
    getEmployee: function() {
        var self = this;
        if (!self._company) {
            return null; //or throw error or return rejected promise: $q.reject('company is null')
        } else {
            var url = '...';
            var name = self._company.name;
            return http.get(url);
        }
    }
}

Testing your service separately from your controller is recommended. For controller tests, you can spyOn your service methods without making actual server calls. When testing the service, simply set the service._company to a mock value for testing the getEmployee method.

Answer №2

The problem lies within your service implementation. Instead of using a string as the "company", it should be an object literal since you are accessing the property .name from it. Otherwise, you will encounter the error that you have mentioned.

Consider the following code snippet:

Service

var company = {};

function getCompany() {
    $http.get(url).then(function(comp){
          company = comp;
          return company;
    })
}

function getEmployee = function() {
    var name = company.name
    $http.get(url).then(function(employee){
        // perform actions here    
    }
}

With this adjustment, the functionality should work as expected.

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

How to access vue.js 3 single file component functions from within a script tag

Imagine having a single file component structured like this: <template> // content irrelevant </template> <script> export default { data() { return { redLocations: [ "Isfahaan", "Qom", ...

Protecting the source code of your Node.js application is just as important

When it comes to the security of the node application, is the source code protected from being viewed by clients like PHP? I am currently working on a website using node.js and I want to ensure that my server files are not accessible to others. While I&apo ...

Exploring the World of 3D Design with Three

Is there anyone out there who can assist me with three.js? I am in need of drawing a background, something like a THREE.Sprite, but it needs to be positioned UNDER any 3D object that will be drawn later. I have a camera that can only move along the Z axis ...

Divide a picture with the help of javascript

Is there a way to utilize JavaScript to extract sections of an image and save them in an array, then showcase them randomly on an HTML5 canvas? ...

Accessing iframe's HTML using a server-side solution by circumventing the Cross-Domain Policy

Our current challenge involves accessing dynamically generated HTML elements using JavaScript, particularly when trying to extract image URLs from these elements. When the HTML elements are generated solely through JavaScript, extracting the URL is straigh ...

Can you explain the significance of `window.jqueryFoo = false;`?

I came across this code snippet within a React component: export default class pageWithModal extends React.Component { constructor(props) { super(props); window.jqueryFoo = false; this.state = { modal: false, value: '&apo ...

Encountering the "Invalid Element Type" error in a Vue Native project right after setting it up

After creating a vue-native project with the command vue-native init henry-pager, I navigated to the directory and initiated the online builder by running expo start. However, when attempting to run it on the web platform, an error message appeared: Error: ...

What is the best method to determine the mean score by utilizing the ID values obtained from API responses?

These are the responses retrieved from the API: const attractions = [ {"id": 1,"name": "drive on avenue"}, {"id": 2, "name": "diving"}, {"id": 3,"name": "visiting ma ...

Accessing the react-bootstrap tab using the history feature in React

Currently, I am in the process of developing a multi-form page that includes login, registration, and lost password functionalities displayed using tabs with react-bootstrap. The technologies I am using for this project are react 17.0.2, react-bootstrap 2 ...

How can I create a top right profile button similar to Google using AngularJS?

I am looking to implement a floating button in the top right corner of my main screen. When clicked, I want it to open a card below with an arrow pointing towards the button similar to the one on . I am currently using Angular Material and have tried using ...

We are creating a table in JavaScript and mistakenly adding an unnecessary tbody

I am currently utilizing a combination of plain JavaScript and Jquery in order to dynamically generate a table. The issue arises when I attempt to use a for loop to iterate through the data obtained from an Ajax request, as it fails to create new rows. To ...

Tips for linking weight scale device to a website

I recently developed a web application that calculates the weight of products. The application was created using PHP, JavaScript, and AJAX, running on a XAMPP server. Now my client is requesting for me to integrate a weight scale machine into the applica ...

Can D3 transform regions into drinking establishments?

I can create a graph using D3 areas, as shown in this example: https://i.sstatic.net/jaxJb.png Now, I want to add an animation to this graph. When the webpage loads, the initial figure will be displayed. Then, each area will morph into a bar chart. Addit ...

Is there a way to display the result array in Node.js after a MongoDB find query has been executed?

I'm new to Node.js and I'm trying to pass an array of data to a controller. However, I'm facing some challenges in inserting for loop data into the array and also looking to access the resulting data outside the function. router.get("/list- ...

Tips for toggling between 3 class names every 5 seconds indefinitely

Is there a way to continuously alternate between different class names on an element with a 5-second interval, like this: Initially, at 0 seconds, the element is assigned the class name 'banner-1' as shown in this code snippet: <div classname ...

ways to manipulate href using JavaScript

Apologies for any grammatical errors in my English. With the use of jQuery, I am trying to achieve the functionality where pressing the arrow keys on the keyboard will redirect to a URL with the #g tag. Specifically, when the down arrow key is pressed, h ...

Vue mouseup and mousedown event not functioning as anticipated

I am experiencing an issue with my code where the button is supposed to be disabled on mousedown event and enabled back on mouseup event. However, for some reason, the button does not get enabled on mouseup event. Here's the snippet of my code: ne ...

Attempting to extract a parameter from a URL and pass it as an argument to a function for the purpose of locating objects based on

I am trying to retrieve data from a URL http://localhost:3000/share/user=sampleuser to display objects with an author value that matches the one in the URL. However, I encountered an error when attempting to call a function that extracts the value from t ...

I aim to create a solution that leverages the power of JQuery Ajax to fetch data from a web page and then uses that data to populate the $scope object, filling the HTML template

angular.module('spLists', []) .factory('spListsFactory', function ($q) { return { getItems: function (url) { var json, div = $('<div>').css('display', 'non ...

Determine in React whether a JSX Element is a descendant of a specific class

I am currently working with TypeScript and need to determine if a JSX.Element instance is a subclass of another React component. For instance, if I have a Vehicle component and a Car component that extends it, then when given a JSX.Element generated from ...