2

Just trying to understand why I'm getting undefined when trying to build up a ng-click call to a method using a jQuery function. Here's one example of it:

<a href="#" class="btn btn-default" ng-click="angularMethod($('input[name=__RequestVerificationToken]').val())">...</a>

on the ng-controller I have:

$scope.angularMethod = function(token) {
    $log.debug(token);
}

which renders me a undefined message on the console.

I have a full jQuery js file being loaded before the angular js file. Wasn't this supposed to be working?

Marcelo Myara
  • 2,841
  • 2
  • 27
  • 36
  • what you are going to achieve by doing this? why you don't assign `ng-model` to it – Pankaj Parkar May 13 '15 at 13:44
  • 1
    why would you ever need to do that? Reason you can't is `$` isn't part of angular scope – charlietfl May 13 '15 at 13:46
  • Suppose I can't. The input on the example is rendered by a ASP.NET MVC helper and I have little control over it. I coulb build my on helper for rendering the input with a ng-model on it, but this is an approach that I'm not confortable on doing. Besides, I can imagine tons of uses for a systax like the above one (and keeping the view more detached from the controller as possible). – Marcelo Myara May 13 '15 at 13:47
  • 2
    You need to completely re-adjust your thinking about how angular works.... the view is totally attached to models in the scope Must read: [thinking-in-angularjs-if-i-have-a-jquery-background](http://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background) – charlietfl May 13 '15 at 13:49
  • @charlietfl, using it with `jQuery('input')` syntax render me the same thing. And when I'm using the same statement inside 'angularMethod' it just works. – Marcelo Myara May 13 '15 at 13:49
  • @charlietfl, thanks for the amazing question link. Will try to change the paradigm over it... But, still... I just can't get why it's not working... It doen't make sense not to work. – Marcelo Myara May 13 '15 at 13:51
  • you are making an incorrect assumption that the global namespace is readily accessible from the code in view...it's not – charlietfl May 13 '15 at 13:54

2 Answers2

2

I have a full jQuery js file being loaded before the angular js file. Wasn't this supposed to be working?

No, ngClick and similar directives are not onclick and etc attributes. It's just some custom attributes with some string values which are parsed and evaluated by Angular (see parse.js if you are interested). Those expressions you can provide, are evaluated in context of the current scope object.

So now you should be able to understand why it won't work in your case. Do you have scope property called $ which is basically points to jQuery? I guess, not. Technically, it's possible to make your example work, however you should not mix jQuery and Angular like this. It will just make your code extremely hard to read and support.

Also check this great question “Thinking in AngularJS” if I have a jQuery background? about working in Angular with jQuery properly.

Community
  • 1
  • 1
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • Ok, I'm getting it. In that case, I could use a regular onclick, attach it to a regular JS method and then fill a scope attribute with the token and call the scope method from there. This would be awfull (i got that now) but it would work, right? – Marcelo Myara May 13 '15 at 13:54
  • 1
    Yes, you could do it with `onclick`: set necessary scope values, trigger scope digest. But it will just soon become unmaintainable. – dfsq May 13 '15 at 13:56
  • 1
    @MarceloMyara no...get rid of jQuery in your page completely, and don't think of MVC as driving your page either. *Think data first* ...then the view and binding the view to the scope data models using angular built in directives first...and custom ones as needed – charlietfl May 13 '15 at 13:56
  • @charlietfl, Ok, i got that from the architectural perspective. But I still needed to understand how those 2 (angular and jQuery) are working together. I know lots of jQuery and too short of Angular. So I just needed to know how jQuery could save me on doing thing's on desperate measures. It's just for knowing the boundaries of this mixing... – Marcelo Myara May 13 '15 at 14:01
  • @MarceloMyara That's why you need to take jQuery out of the page completely and get out of *DOM first* thinking. That input would be bound to scope model using `ng-model` and you wouldn't need an argument in function at all – charlietfl May 13 '15 at 14:10
  • 1
    @MarceloMyara jQuery is just a very useful set of methods for (mainly) DOM manipulations. In Angular you don't worry about DOM that much as you are used with jQuery, but focus on data manipulations. When you need to work with DOM you just create custom directives and do you work there, using jQuery if you want. – dfsq May 13 '15 at 14:15
0

Check This fiddle I´ve prepared for you to show the different solutions you can use with angularjs:

http://jsfiddle.net/joshdmiller/HB7LU/

<div ng-controller="MyCtrl">
<input name="__RequestVerificationToken" ng-model="myvalue">
<a href="#" class="btn btn-default" ng-click="angularMethod(); angularMethodTWO()" ng-model="myvalue">CLICK</a>
</div>




var myApp = angular.module('myApp', []);

function MyCtrl($scope) {
$scope.name = 'Superhero';

$scope.angularMethod = function () {
    alert("WITH NG-MODEL:" + $scope.myvalue);
}

$scope.angularMethodTWO = function () {
    alert("WITH ANGULAR ELEMENT:" + angular.element(document.querySelectorAll("[name=\'__RequestVerificationToken\']")).val());
}
}

Hope it Helps!!

EDIT changed jsfiddle url with a newer version (the other one was not the right one)

  • 1
    wouldn't hurt to show model value as text either for OP to see live page updates – charlietfl May 13 '15 at 14:14
  • It's not working. I thing you forgot to register the controller on that module... But anyways, I got it. The thing is: I don't have control over the input for __RequestVerificationToken (so I cant add the ng-model directive on it). That's the challenge... – Marcelo Myara May 13 '15 at 14:19
  • I don´w know what happened with the fiddle version... please wait!!! it just gone to another one before!! – Alejandro Teixeira Muñoz May 13 '15 at 14:23