9

I'm writing some tests for an Angular directive and I need to simulate user input into an input field. I tried to do this:

element.find('input').val('some value').trigger('input');

but it didn't work. Triggering change didn't work either. I know I can access the element scope directly with element.scope() and change it, but it seems more natural to change the input's value and let Angular do the data binding.

For what it's worth, I've checked out input(name).enter(value) from Angular ngScenario, and it seems to do the same as I did:

...
input.val(value);
input.trigger(event || (supportInputEvent ? 'input' : 'change'));
...

What am I missing? Is there a better way to test user input in this case?

(I made a jsFiddler script to illustrate the question)

UPDATE

I think some clarification is needed. I'm not trying to change the DOM nor the scope outside Angular realm per se. I have a directive that renders an input box bound to a property of the directive's scope. I'm writing automated tests to ensure the directive does what it's supposed to do, and what one test should do is to simulate some input so that the directive scope gets updated and I can assert that some behavior is performed on that input. As I mentioned earlier, I can change the directive's scope from the test code by using element.scope(), but I'd rather change the input's value and let Angular do its thing.

2
  • How do you test your directive? The way you trigger an input event looks right to me. You are doing this in a test file, right? Commented Nov 12, 2013 at 21:19
  • @ghiden I've already had my question answered - see below. Thanks for your interest, though. :) Commented Nov 12, 2013 at 22:02

2 Answers 2

7

After spending some more time researching and testing, I've figured out what was wrong: jqLite registers event handlers using addEventHandler and they don't get triggered by jQuery trigger function. My jsFiddle script wasn't working because Angular's script was being loaded before jQuery's (and therefore was using jqLite). I updated the script to load everything in the correct order so that Angular uses jQuery on function to register event handlers, and now it simulates changes on the input box and tells Angular to do the data binding.

My test code wasn't working for the very same reason. I fixed it by changing the scripts order as well. If I didn't happen to be using jQuery, I would have to trigger the event by calling dispatchEvent instead of trigger.

8
  • 2
    jQuery's trigger does fire handlers hooked up via addEventListener: jsbin.com/APEwimu/1 (source: jsbin.com/APEwimu/1/edit). This has been true for a long, long time (1.2.6 was as far back as I decided to go). Tested on Chrome, Firefox, and IE8 - had to edit the script for that last, of course, because it wants attachEvent. Commented Oct 15, 2013 at 7:13
  • @T.J.Crowder That's odd. Could you help me understand why my first script doesn't work? Commented Oct 15, 2013 at 14:47
  • I'm getting a $apply already in progress error--did you ever run into this when manually triggering an 'input' event? Commented Dec 12, 2013 at 19:50
  • @bennlich No, not that I can remember. Are you doing that in the context of unit tests? Commented Dec 12, 2013 at 20:18
  • No--that might be the difference. I wonder if digest cycles work differently there? Commented Dec 13, 2013 at 0:12
-2

This is not right approach to do this in angular. You should do like this.

Working DEMO

Create function inside the $scope and change your variable value so that angular itself will update your input field as well as at all places where you have used(bind) this variable.

Angular Function

$scope.changeInput = function() {
    $scope.value="barfoo";
}
1
  • I'm afraid that doesn't answer my question. I'll update the post to make things clear. Commented Jul 30, 2013 at 17:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.