AngularJS binding json to a form input - angularjs

I can easily bind data to a div or pre tag with the code:
<div id="json_route{{route.id}}" ng-bind="items.route{{route.id}} | json"></div>
However, I want to try and bind this data to a hidden form input, I tried:
<input type="hidden" name="json_route{{ route.id }}"
ng-model="items.route{{route.id}} | json" />
Which returns me an error of:
Error: Non-assignable model expression: items.route2 | json (<input type="hidden" name="json_route2" ng-model="items.route2 | json">)
So obviously I cannot use | json when using ng-model. The angular docs are still a bit sparse and I can't seem to find how to assign this correctly, even if I can? Thanks :)
I need to get this json data loaded into my pyramid application, and assigning it into a hidden form field seemed the best way todo it, or should I be doing this in a different way?

"To be able to render the model into the view, the model has to be able to be referenced from the scope." (src: Angular Guide).
Angular needs to be able to reference the value in your ngModel expression to a $scope variable in your controller.
With ng-bind it worked, because ng-bind is not the same as ng-model. ngBind simply takes your expression and evaluates it inside the current scope and than replaces the text of the host element with the result. As Guide tells us, the value of ng-model must be an assignable angular expression to data-bind to.
To have your hidden input contain the json string representation of your 'items.route2' model you could setup a $watch expression in your controller which would "prepare" the json string of your model whenever it changes. See plnkr example.

Try using ng-init:
<input type="hidden" name="..." ng-model="items.route{{route.id}}"
ng-init="items.route{{route.id}} = data_from_server_here">
See also https://stackoverflow.com/a/12657601/215945.

Related

when should I write code with `{{}}` and without `{{}}` in html of angular js project

May be This is a simple question but it is challenging for me.
In angularJS when i write {{}} in html code so i write code like this like
if i talk about dynamic id, we write like code this
<div ng-repeat = 'item in itmes track by $index'>
<div id = "div-{{$index}}">{{item.name}}</div>
</div>
If i use any model without {{}} i write this example
<input id = 'name' ng-model = "item.name"/>
whenever i am coding in angular js, i write code without {{}} then if it is not work then i try code with {{}} and vise versa. and randomly 1 will correct
Question is when i write code with {{}} and without {{}} in html code ?
After the OP explained what exactly was the problem.
So, the question here is very simple: when do we use {{}} and when we don't in the context of ng-model.
When you do a <input type=... ng-model="someModel>, what you're essentially telling Angular is: "Here is an input element; attach $scope's someModel variable to the value of this input element.
Now, you can use this in your JavaScript controller like so: $scope.someModel, but what about HTML? We have a templating language in Angular, and when you give it some variable (say someModel), it'll search its $scope for it, and then put in the value there. If it is unable to, it'll throw a nasty error.
In essence, {{}} GETS the value, without that, you generally set the variable to gold the value of something.
Very simply put, AngularJS thinks that the content within the brace is an expression, which must be resolved. Once it is, Angular puts the value of the resolved expression there. In the most basic of the terms, you just tell it: "Here is some expression; put the evaluated value instead."
In ES6, we call it template strings.
So, you'll use it for expressions which mutate after every iteration. Say, a loop or something. Places where you know what the answer is, or you have static content, you won't use it.
Say you have the following bit of code:
...
...
$scope.figureOne = 10;
in your controller.js and the following in its view file:
<div>My age is {{ figureOne }}</div>
Angular gets the value from the $scope, and puts it there; so, the rendered form will be: My age is 10. However, if you had the following
<div>My age is figureOne</div>
This time, Angular knows that there is nothing to evaluate or resolve, so, it'll just render it as it is: My age is figureOne.
I hope I made it clear! :)
Angular directives have different types of parameters. Some parameters (#) expect string values and some expect javascript expressions (=) (with variables bound to $scope).
There's no obvious way to know which parameter expects what type of value (aside from looking at documentation).
If a variable expects static string value and you have an angular expression
then you'll need to evaluate it by wrapping in {{}}
If there variable expects an expression and you have an expression
simply type that in.
It's the best to avoid using {{}} where possible, your dynamic ID will fail when Angular hasn't interpolated the expression yet, use ng-attr-id="div-{{$index}} for that. https://docs.angularjs.org/guide/directive#-ngattr-attribute-bindings
Another example, if you have a slow connection and Angular isn't loaded yet users will see the {{}}, you can avoid this by using ng-bind="".
See this thread for more info: AngularJS : Why ng-bind is better than {{}} in angular?
It is very simple.
{{something}} - used for one way binding(Static).
<input type="text" value="{{something}}">
Now if you change its value in HTML ,you can not get it by $scope.something in js.
but If you use ng-model="something",you can get its value in JS.
This happens because ng-model is two way binding.
<input type="text" ng-model="something">
Mostly We use ng-model for forms and {{}} to display static information like User details or else.

Dynamic object field assign by another model

I have a task:
dynamicly generate 2 inputs calls "name of field" and "value of field" and then put data to object in $scope
example
first input value is "angrular"
second input value is "awesome"
as a result I get custom object with field "angular" and value "awesome"
P.S. Sry for poor level of English
You can achieve this only with markup, making use of the directives ng-model and ng-change:
<div ng-app>
<input ng-change="obj[propName] = propValue" ng-model="propName"/>
<input ng-change="obj[propName] = propValue" ng-model="propValue"/>
<div>Result: {{ obj }}</div>
</div>
... though you said "dynamically generate 2 inputs", which may imply the task involves having the ability to add multiple properties to the result object. This live example shows a way to do that.
Check the docs:
ngModel
ngChange

AngularJS: Why I can't print a model variable directly (instead of using $modelValue property)?

In my view I have this form:
<form name="form1">
<input name="msg" id="msg" ng-model="form_data.msg">
</form>
In my controller I get the content of the input by
var message= $scope.form1.msg;
however when I insert some text (e.g. "test_abc") and try to print the contentof the input (within the controller), I get an object instead of the actual value. In fact
console.log(messageToSend);
gives this output
[DEBUG] message >>: [object Object]
controllers.js:646 Object {$viewValue: "test_abc", $modelValue: "test_abc", $$rawModelValue: "test_abc", $validators: Object, $asyncValidators: Object…}
Of course I can just get $modelValue, but I noticed that (sometimes) I can work with the model value (just by using $scope.modelVarName) it instead of printing it.
Sorry if this is quite vague but I can't find a concrete example right now.
However, just to sum up, I need to understand: is there a way (other than using .$modelValue property) to retrieve (within the controller) a model variable defined (in a form within a view)?
<input name=msg ng-model="form_data.msg"> with this markup the value of the input will be updated in the controller scope's form_data.msg property. [form_data is an object].
Angular will update the validation related info of the input field in form1.msg of controller's scope. Here form1 is the name of the form and msg is the name of the message. This is not the actual model. Your actual model is form_data.msg. form1.msg will contain the validation related information.
If you want to print the model use form_data.msg not form1.msg
I use your code in jsfiddle and it worked, with a little changes, I just define app and use
{{form1.msg}}
to print the value.
Here's the jsfiddle:
http://jsfiddle.net/diegounanue/5bbkmk3m/

angular "query" property : where is it defined?

AngularJS noob here.
I'm going thru the tutorial (https://docs.angularjs.org/tutorial/step_03) and see this in the example index.html template:
Search: <input ng-model="query">
I don't see any mention of a 'query' property in the accompanying JS files (controllers.js, etc).
Is query a property of the $scope object? If so is there a documentation for it? Can't seem to find one.
Thanks!
In this example query is not used in the JavaScript at all, so it isn't mentioned there.
It is created by <input ng-model="query"> and later used by the filter in phone in phones | filter:query.
With this html Angular watches for changes to query from typing into <input> and then reapplies the ng-repeat passing the new query value to filter.

How to get the NgModelController for input fields inside a ngRepeat directive?

Normally, with a form and input fields, the form controller is published into the related scope under the form name attribute. And, the NgModelController is published under the input name attribute.
So for an input field with an ngModel directive, the NgModelController for the input field can be retrieved like $scope.myFormName.myInputFieldName
The question is how to do the same thing (get the NgModelController) for input fields inside the ngRepeat directive?
I would like to name the input fields using $index as part of the name so each template instance is uniquely named. This renders OK, so
<input name="foo_{{$index}}" ...
renders the instance with $index == 3 to
<input name="foo_3" ...
But trying to get the ngModelController via the published names does not work (it's undefined), e.g.:
$scope.myFormName.foo_3
A plunker showing this is here: http://plnkr.co/edit/jYDhZfgC3Ud0fXUuP7To?p=preview
It shows successfully getting the ngModelController for a 'plain' input element and calling $setValidity, and also shows failing to get the ngModelController for an input element inside an ngRepeat directive.
Copied the relevant section of code from the plunker below:
<div ng-repeat="element in elements">
<div ng-class="{error: form['foo_{{$index}}'].$invalid}">
<input name="foo_{{$index}}" ng-model="element.a" type="number">
<span ng-show="form['foo_{{$index}}'].$error.bar">ngRepeat bar invalid</span>
</div>
</div>
{{form.foo_0.$setValidity('bar', false)}}
#Flek is correct that the new child scopes that ng-repeat creates are the root of the problem here. Since browsers do not allow nesting of <form> elements, ngForm must be used when nesting forms, or when you want to do form validation inside ngRepeat.
See Pawel's answer on the google group thread, which shows how to use ng-form to create inner forms, and/or #blesh's SO answer.
If i understand your question correctly, you are trying to have access to the form elements created inside the ng-repeat.
Please have a look at this fiddle http://jsfiddle.net/EF5Jp/. Inside the button click handler you will have the access to the element with id myForm.foo_2. You can notice that the element is retrieved by myForm.foo_2 and not $scope.myForm.foo_2. Second thing is, changing the value using its scope and not using its value property like angular.element(element).scope().foo = 6;.

Resources