What is the best way to test a JavaScript function that includes nested timeouts using Jasmine?

I have a function that clears an input on blur. It's designed for use with Angular Materials, and I've created a directive for when this functionality is needed.

function clearTextOnBlurLink(scope, element, attrs, controller) {   
    $timeout(function() {
        var input = element.find('input'); 
        input.on('blur', function(e){
            setTimeout(function(){
                input.val('');              
                input.triggerHandler('input'); 
            }, 100);                
        });
    },0);
}

I'm trying to test it out, but having some trouble getting it to work.

Here's my testing code:

beforeEach(inject(function(_$rootScope_, _$compile_, _$timeout_) {

    $scope = _$rootScope_.$new();
    $compile = _$compile_;
    $timeout = _$timeout_;        
    $scope.searchText = 'blah';

    element = angular.element('\
        <div mx-clear-on-blur>\
        <input ng-model="searchText1">\
        </div>\
    ');

   element = $compile(element)($scope);
   $scope.$apply();
   $timeout.flush();       
}));

it('clears text on blur', function() {
    var input = element.find('input').eq(0);

    expect(input.val()).toBe('blah');
    expect($scope.searchText).toBe('blah');

    input1.triggerHandler('blur');

    expect(input.val()).toBe('');
    expect($scope.searchText).toBe('');

});

After making some changes by replacing setTimeout with $timeout, I managed to make it work. Is there a smoother way to achieve this without using two timeouts?

Answer №1

Have you considered why you are resorting to using setTimeout for the second time instead of just sticking with $timeout once more? Additionally, relying heavily on $timeout can sometimes indicate a potential issue in the code structure, so having nested $timeouts might not be the best approach. :p

By the way, in order for your test to pass successfully, you may want to include a $timeout.flush() in your test script following the blur event.

Answer №2

Incorporating setTimeout into your test is possible:

input1.triggerHandler('blur');
setTimeout(function() {
    expect(input.val()).toBe('');
    expect($scope.searchText).toBe('');
}, 100);

An alternative method in Jasmine is waitsFor:

input1.triggerHandler('blur');
waitsFor(function() { 
    return false; 
}, 100);
expect(input.val()).toBe('');
expect($scope.searchText).toBe('');

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

insert data into modal's interface

I'm encountering an issue with my code, where the modal is not displaying the values inside the brackets as if they were not bound correctly. Everything else in the ng-repeat seems to be working fine, but for some reason the values are not being displ ...

When it comes to JavaScript, the evaluation order of arguments and delayed evaluation play a crucial

Assuming function( arg1, arg2 ), is it true that arg1 will always evaluate before arg2 (unlike traditional C)? Is there a way to create a function where arguments are not evaluated immediately, but only on demand? For instance, in if( cond1 || cond2 ), c ...

What's the issue with reducers receiving a Function instead of an Object in Redux?

I encountered an error in my react and redux project but I am unable to figure out how to fix it. Here is the error message: The reducer received unexpected type "Function" as the previous state. It was expecting an object with keys: "posts", "sidebar" ...

The process of altering a grid in HTML and adding color to a single square

I am facing a challenge that I can't seem to overcome. I need to create a game using HTML, CSS, and JS. The concept involves a grid where upon entering a number into a text box, a picture of a cartoon character is displayed in a square which turns gre ...

"Maximizing the slider with jCarousel: A guide to enhancing your carousel experience

I recently added jcarousel to my website and things are looking good so far. Take a peek at how my site is currently set up: check it out! What I'm aiming for now is a feature where if a user clicks on an image to enlarge, it will open in a new tab ...

Leverage AJAX on the client-side for optimal performance while utilizing node.js

I am currently working on a simple nodejs application that displays HTML pages. Within this application, there are two buttons that are linked to JavaScript functions in separate files. One of the functions uses ajax, while the other does not. However, I a ...

What role does a promise play in rendering code asynchronous?

While we often use promises to avoid the dreaded function callback hell, a question remains: where exactly in the event loop does the promise code execute and is it truly asynchronous? Does the mere fact that the code is within a promise make it asynchron ...

Fire the click event following the parsing of the HTML page

Is it possible to programmatically navigate to a URL, retrieve the response, and then activate the JavaScript click event of an HTML element within that response? For example, if the response contains an element like this: <div id="test">Click me< ...

"Encountering a new error with the creation of a user using AngularJS and Firebase

Attempting to create a user using Angular. myApp.controller('loginCtrl',['$scope','$firebaseAuth','config',function($scope,$firebaseAuth,config){ console.info('[APP-INFO] ~ loginCtrl Start') var ref = ne ...

Is it possible for ng-options to function independently of a controller?

Is it possible to populate a select dropdown in an Angular component using an array of strings as option tags without the use of a controller? How can this be achieved? Within the component, I have defined the following variables: array: String[] = [&apo ...

Receiving Server Emissions in Vue/Vuex with Websockets

In my Vue component, I was using socket.io-client for WebSocket communication. Now that I've added Vuex to the project, I declared a Websocket like this: Vue.use(new VueSocketIO({ debug: true, connection: 'http://192.168.0.38:5000', })) ...

Activate the HTML drop-down option upon selecting the radio button, or the other way around

I'm attempting to accomplish a task. Below is the code snippet I am working with: <form> <input type='radio' name='radio_flavour' checked/>Unique flavour<br/><input class='double-flavoured' type=&apo ...

What is the best way to extend an inline-block element to cover the entire text line?

Let's talk about the scenario: https://i.stack.imgur.com/we05U.png In the image, there is a container (displayed as a div) with only one child - a span element. The goal is to introduce a second child that occupies the entire red space depicted in t ...

Error: the search variable is not defined

function sorting(type) { $("#parentDiv").empty(); $.getJSON("example_data.json", ({ Find })); function Locate(a, b) { return (a[Find.type] < b[Find.type]) ? -1 : (a[Find.type] > b[Find.type]) ? 1 : 0; }; } The example_data.j ...

How to Implement Button Disable Feature in jQuery When No Checkboxes Are Selected

I need help troubleshooting an issue with a disabled button when selecting checkboxes. The multicheck functionality works fine, but if I select all items and then deselect one of them, the button disables again. Can someone assist me with this problem? Be ...

unable to clear form fields after ajax submission issue persisting

After submitting via ajax, I am having trouble clearing form fields. Any help in checking my code and providing suggestions would be greatly appreciated. Here is the code snippet: jQuery(document).on('click', '.um-message-send:not(.disabled ...

Exploring the differences between utilizing Node JS Express for server-side development and displaying console output to

Recently, I started delving into the world of node js and came across IBM's speech to text sample application (https://github.com/watson-developer-cloud/speech-to-text-nodejs). This app utilizes the express framework and showcases transcribed audio fr ...

Obtain the Week Input's Value

Is there a way to store the value of a week input in a variable and then display it in a span? I attempted the following code: <input type="week" name="week" id="week-selector"> <span id="kalenderwoche"> ...

Ways to execute a function only once within setInterval

Hey there, I'm facing an issue with this... getSocketPerSecond = function () { Interval_PerSecond = setInterval(function () { $.ajax({ url: "/asset/ashx/GetSocket.ashx", type: "post", ...

Is there a way to implement an onclick event on a specific line of text that triggers a popup box only when the text is clicked, without the popup appearing automatically when

I received assistance from a fellow user to customize a popup that turned out great. However, I'm having trouble getting the onclick function to work properly so that the popup only appears when the phone number is clicked. Ideally, I want the phone n ...