1

I have the following code:

<input id="id">
<button data-action="bea" ng-click="Create($('#id1')[0].value);" class="btn">Insert ID</button>
<button data-action="bea" ng-click="Create($('#id2')[0].value);" class="btn">Insert ID</button>

In the JS I have:

$scope.Create = function (id){
        if (id === undefined) {
            $scope.data = "You must specify an id";
        } else {
                $scope.data = data;
                console.log(data);
            });
        }
    };

When the call gets into the Create function the value of the id is undefined.

If I add the following line at the beginging of the Create function everything works ok:

id = $('#id')[0].value;

If I send a constant value it works:

<button data-action="bea" ng-click="Create('SomeID');" class="btn">Insert ID</button>

Why is this happening and how can I do that without putting the line of value into the method?

Thanks

PSL
  • 123,204
  • 21
  • 253
  • 243
Randall Flagg
  • 4,834
  • 9
  • 33
  • 45
  • 1
    Makes no sense to me on why it should ever work!! still in the world of extensive direct DOM access and manipulations? [This answer](http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background) should help you rethink.. – PSL Oct 16 '14 at 01:18
  • @PSL This is not a very useful comment. I know the link u sent me. Can u please explain what I did wrong? – Randall Flagg Oct 16 '14 at 01:29
  • 1
    It depends upon what you see as useful. You are mixing things without completely understanding angular concepts. In angular world in controllers you dont really access DOM elements, you instead do data bindings and let angular manage DOM. If you read that link, it will clear up a lot of things. WHat is the element with `#id` ? and input right? so you would just do `` in your controller and you would just access its value as `$scope.myModel`. Angular is more opinionated in all these things. – PSL Oct 16 '14 at 01:30
  • 1
    Here is an example of how you may do this with angular http://plnkr.co/edit/IemE00?p=preview – PSL Oct 16 '14 at 01:37
  • Thanks for the sample. I tried it. My problem with this solution is that I can't use the same method if I have more then 1 input because I am using an explicit name. Or am I wrong? – Randall Flagg Oct 16 '14 at 01:43
  • You could pass `id` in the function as well. Check that demo link again. As i said it is just an example, you can really explore further (official documentation has lots of examples) and write some awesome angular code :) . – PSL Oct 16 '14 at 01:45
  • Sure il do it.. if you think it helped. – PSL Oct 16 '14 at 01:55

4 Answers4

5

This is just an extension of comments and other answers, You could achieve this in many ways using angular, one simple example could be:-

  <!-- Add a controller -->
  <div ng-controller="MainCtrl"> 
     <!-- Give a model binding to your text input -->
     <input ng-model="userEntry" type="text"/> 
     <!-- ng-click pass which ever argument you need to pass, provided it is an expression that can be evaluated against the scope or any constants -->
     <button data-action="bea" ng-click="Create(userEntry);" class="btn">Insert ID</button>
    <!-- Some simple data binding using interpolation -->
    {{data}}
     <!-- Just for demo on repeater on a list of items on the scope -->
     <div ng-repeat="item in items track by $index">{{item}}</div>
  </div>

Example Demo

My 2 cents on the lines of what were originally trying to do:-

Use angular bindings instead of accessing DOM directly for getting the data, it really helps you deal with just the data without worrying about how to access or render it in DOM. If you think you need to access DOM for implementing business logic re-think on the design, if you really need to do it, do it in a directive. Angular is very opinionated on the design and when where you do DOM access.

PSL
  • 123,204
  • 21
  • 253
  • 243
  • Take a look at angular validations, parsers, formatters, animation, and lot and lots of stuffs. Official documentation is very good to start with, it has lots of examples as well. – PSL Oct 16 '14 at 02:08
1

My guess is that $ is not bound to the jQuery function when the ng-click value is evaluated, because it is not exposed in the Angular scope.

Solutions to adress this:

  • expose the jQuery function in scope somewhere, e.g $scope.$ = $; in a controller.
  • make the Create function parameterless as you suggested, with a var id = $('#id')[0].value; at the beginning
  • my favorite : avoid using jQuery. If you put some data in the #id element, there's probably a more natural and AngularJS-idiomatic way of retrieving it than querying the DOM (e.g an Angular service).

In particular, if the element you're targeting is an <input> element, then use the ngModel directive to link the value to a $scopeproperty that will be accessible in the controller :

<input ng-model="inputData"/>
Valentin Waeselynck
  • 5,950
  • 26
  • 43
  • What is that way? Is it what PSL suggested? – Randall Flagg Oct 16 '14 at 01:36
  • Yes, basically your controller should not know about your view. It just exposes data for your view to represent. The question is : where does the content of this element come from? – Valentin Waeselynck Oct 16 '14 at 01:38
  • I would not even consider #1 and #2 bullet points. #3) depends when and where you want to use it. – PSL Oct 16 '14 at 01:39
  • @PSL : Agreed, #1 and #2 are hacks to me. – Valentin Waeselynck Oct 16 '14 at 01:40
  • The data I want comes from the user. There might be more then 1 input tag there. – Randall Flagg Oct 16 '14 at 01:44
  • +1 for answering the question the OP asked whilst still educating and encouraging a solution more in line with the AngularJS way of doing things. As other have made clear, solutions #1 and #2 are not recommended and a last resort. Other developers will not look kindly on code that has to use these sorts of techniques. – GregL Oct 16 '14 at 01:51
1

This is not the way you should do in AngularJS. You should really think in Angular if you want to use AngularJS. Refer this post ("Thinking in AngularJS" if I have a jQuery background?)

All DOM manipulation should be done in Directive. Refer this page that I found really clear. (http://ng-learn.org/2014/01/Dom-Manipulations/)

Community
  • 1
  • 1
geckob
  • 7,680
  • 5
  • 30
  • 39
  • Oops, i mentioned something like this in my comments as well, but OP did not like it.. :/ – PSL Oct 16 '14 at 01:38
  • @PSL OP didn't like that because it didn't explain what I am doing wrong and how to solve it. :) – Randall Flagg Oct 16 '14 at 01:49
  • haha sorry, i thought that answer you had might help!! should have been more explicit.. – PSL Oct 16 '14 at 01:51
  • 1
    @PSL It takes some time to move from JQuery thinking to AngularJS. Understandable. If he can clarify what he is trying to do, maybe people can suggest how that can be done using the built in directives that Angular have. – geckob Oct 16 '14 at 01:52
  • @lookman +1 for having similar opinion as myself to start with.. :) and yes i agree with you. – PSL Oct 16 '14 at 02:06
0

The JavaScript you are trying to pass as a parameter of the create function is not available in the scope of the Create function.

Try to target the element a different way.

Does that help?

Nice-Guy
  • 1,457
  • 11
  • 20