murtaza52
murtaza52

Reputation: 47441

how to pass a json as a string param to a directive

When I try to eval the below json form it gives me an error -

eval("{form: 'form' , nameToMatch: 'password1'}")

Why is the above form not valid ?

However the below works fine -

eval("{form: 'form'}")

I am trying to pass the above json as a string, as a param input to a directive.

Below is the html -

<input type="password" name="password2" ng-model="user.confirmPassword" placeholder="Confirm Password" match="{form: 'form', nameToMatch: 'password1'}" required="required"/>

Thanks, Murtaza

Upvotes: 8

Views: 27400

Answers (5)

pixparker
pixparker

Reputation: 3511

Use JSON.parse(string) in angular. be sure that your parameter is in string format.

Upvotes: 0

Ben
Ben

Reputation: 57209

Doesn't seem like an angular question though.

Agreed - vanilla JS can handle this just fine.

// Markup (HTML)
<div mydirective='{"test1": "foo", "test2": "bar"}'></div>

// App (JS)
JSON.parse(attrs['mydirective']);

Upvotes: 1

XML
XML

Reputation: 19498

See also. @Blesh has mentioned in passing, but not emphasized: Angular provides you with a 'safe'-ish version of eval(), which works perfectly for passing declarative objects/arrays into your directive if you don't want to declare them on your scope, and wisely don't want to use native eval(). In the OP's example, just use this inside the directive:

angular.$eval(attrs.match);

Upvotes: 2

Ben Lesh
Ben Lesh

Reputation: 108471

Put parens around your json:

 eval("({form: 'form' , nameToMatch: 'password1'})")

Doesn't seem like an angular question though. Not sure what you're trying to do:

Anyhow, to pass the json to the directive there are lots of ways to do that. I'm not sure why you'd want to do that and not just pass an object though.

passing json can be done a lot of ways...

  1. From your attributes object:

    app.directive('foo', function () {
       return function(scope, element, attrs) {
           var obj = eval('(' + attrs.foo + ')');
       };
    });
    

    where

    <div foo="{'test':'wee'}"></div>
    
  2. From an isolated scope:

    app.directive('foo', function () {
       return {
         restrict: 'E',
         scope: {
          'jsonIn' : '@'
         },
         link: function(scope, element, attrs) {
           var obj = eval('(' + scope.jsonIn + ')');
         };
       };
    });
    

    where

    <foo json-in="{'test':'wee'}"></foo>
    

But it's by far better to avoid using the native eval at all costs, if you can. Which in almost all cases you can. If you have some data just put it in an object on a scoped parameter and pass it in either via a two-way property on an isolated scope, or by name and do an angular $eval on it.

EDIT: The pass an object in...

You could use two way binding on an isolated scope:

app.directive('foo', function (){
  return {
     restrict: 'E',
     scope: {
        'data' : '='
     },
     link: function(scope, elem, attrs) {
        console.log(scope.data);
     }
  };
});

where

<foo data="{ test: 'wee' }"></foo>

The really cool thing about doing it this way, is if you're using a scoped property it will update bi-directionally:

app.controller('MainCtrl', function($scope) {
    $scope.bar = { id: 123, name: 'Bob' };
});

where

<foo data="bar"></foo>

I hope that helps.

Upvotes: 22

Jay
Jay

Reputation: 19857

It looks like you are trying to confirm a password in a form. There are many ways that you can go about this without resorting to JSON to pass values around in AngularJS. The most useful resource I've found online is from this Google Group thread:

1) http://jsfiddle.net/pkozlowski_opensource/GcxuT/23/ will compare value in a second field with model value of the first field

2) http://jsfiddle.net/S8TYF/ will compare value in a second field with input value of the first field

The difference might be subtle but has practical consequences: with (2) the confirm validation will kick-in as soon as you start typing anything in the first field. With (1) the confirm validation will kick-in only after the first field is valid. In the e-mail confirm example it means that you won't start showing confirmation errors till e-mail validation errors are sorted out (so a user can focus on one error at the time).

Source: https://groups.google.com/d/msg/angular/R4QeNsNksdY/migbplv8GxIJ

From the first link, the directive is used as follows:

<label>e-mail</label>
<input name="email" type="email" required ng-model="email">  

<label>repeat e-mail</label>
<input name="emailRepeat" type="email" required 
       ng-model="emailRepeat" 
       ui-validate-equals="email">

Where the ui-validate-equals directive points to the email model that was defined in the first input.

There are some StackOverflow answers to this if you would like to look there as well for additional ideas to solve your problem.

Upvotes: 2

Related Questions