angular "query" property : where is it defined? - angularjs

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.

Related

How to use ng-model as element rather than attribute?

I want to use ng-model directive as element rather than as attribute inside tag,is there any way to do it?
well I've already designed my webpage in html and javascript and I want to include it in angularJS using "ng-include". So rather than adding attribute like,
<input type="checkbox" id="checkbox" name='rejectedPartsConfirmtodothis' ng-model="reject">
I want to put it in the format like, (as said in angulaJS documentation )
<ng-model>
<input --->
</ng-model>
but this is not working, any idea how can I make it work?
Quoting the content of the page
Usage
as element: (This directive can be used as custom element, but be aware of IE restrictions).
<ng-model>
...
</ng-model>
according to v1.5 official documentation : https://docs.angularjs.org/api/ng/directive/ngModel
Usage
as element: (This directive can be used as custom element, but be aware of IE restrictions).
<ng-model>
...
</ng-model>
I dont really think there would be a use case where you would really need to do this...instead try some alternative but use ng-model as an attribute as ng-model is a pre-defined directive given by angularjs...
You can build a new directive but you cannot modify ng-model to work as an element.

What magic does ngModel use that modifying the scope directly does not?

Learning angularjs at the moment, and I am confused as to how I can accomplish a task because I don't fully understand what ngModel is doing.
If I have a directive with two scope variables:
// An array of all my objects
$scope.allMyObjects
// The currently selected object from the array
$scope.selectedObject
and in the html
<span>{{ selectedObject.name }}</span>
<select id="select"
ng-model="selectedObject"
ng-options="object in allMyObjects">
</select>
This all works perfectly, when I select an object from the select, it updates the selectedObject on the scope and so the name of the currently selected object is displayed.
However, I don't want a select box, instead I want a list of all my objects with an editable name field, with a select button that I can use to select the specified object, so I came up with the following:
<div ng-repeat="object in allMyObjects">
<input class="object-name"
ng-model="object.name">
<a ng-click="loadObject(object)">Load</a>
</div>
and the loadObject() function on the scope:
function loadObject(object) {
$scope.selectedObject = object;
}
However, this doesn't work. I had assumed this was basically what ngModel was doing behind the scenes but am obviously confused. Is anyone able to shed some light or offer a better solution to what I wish to achieve?
Please see here :http://jsbin.com/jocane/1/edit?html,js,output
use ng-model="object.name" instead "sc.name"
<div ng-repeat="object in allMyObjects">
<input class="object-name"
ng-model="object.name">
<a ng-click="loadObject(object)">Load</a>
</div>
After an hour of debugging it came down to an issue with the scope being isolated by the ng-repeat, the problem didn't show up in any of the simplified jsfiddle examples because they used pure JS and it was the way I was accessing the scope via typescript that caused the issue.
Thanks for the answers that helped me narrow it down to my difficulty understanding typescript and not my difficulty understanding directives.

Limit Angular UI-Bootstrap Typeahead to specific object property

I have the following Angular UI-Bootstrap typeahead working great:
<input class="span2" type="text" ng-model="selectedStuff" typeahead="stuff as stuff.name for stuff in stuffs | filter:$viewValue"/>
Though, it's almost working too great. I'm able to display the stuffs.name for the purposes of the typeahead AND select the full stuff object in stuffs. The problem is that my $viewValue is matching all of the properties in stuff instead of just the stuff.name. I've tried adding the .name to various places in the typeahead with no luck. Is there a straightforward way to display and match only the .name but still return the entire object?
The typeahead directive from the http://angular-ui.github.io/bootstrap/ repo was build to well fit into existing AngularJS ecosystem. This means that this directive tries to re-use as much as possible of syntax, filters and directives already used in AngularJS.
Back to your question - the filtering itself is done by the Angular's filter filter described here: http://docs.angularjs.org/api/ng.filter:filter The mentioned filter's syntax is flexible enough to limit searches to a selected set of properties:
typeahead="stuff as stuff.name for stuff in stuffs | filter:{name: $viewValue}"
Please notice: filter:{name: $viewValue}
Working plunk here: http://plnkr.co/edit/o1qWKq8LSmbbmVaYkOvb?p=preview

angularjs value on load incorrect

See this plunk
I want to use an object model on an input (for interaction with the angularui bootstrap typeahead). It works perfectly when selecting something from the typeahead, but on load it displays [object Object] How can I get the input to display a property of the model object on load?
Just in case someone else landed here just like me, having a [object Object] being displayed in some input(s)...
In my case, I named the form element with the same name of the model property, like this:
<form name="contact">
<input type="text" ng-model="contact.name" />
<input type="text" ng-model="contact.email" />
</form>
Either change the form name to a different name, or change the model name.
As Angular populates the $scope with a property with the same name as the form, it overrides the model instance!
I came across this also and docs don't show how to hook into bootstrap updater callback.
I did it by setting initial value to string. When you type in the field model will be a string. When you select from dropdown it will be object
app.controller('MainCtrl', function($scope) {
$scope.data = [{id:1,name:"google"}, {id:2, name:"microsoft"}];
$scope.selected = '';
$scope.$watch('selected',function(newVal,oldVal){
if(newVal && angular.isObject($scope.selected)){
console.log($scope.selected)
}
})
});
Plunker
Perhaps ther is a better way using directive's attributes but not sure what that is
Turns out there is currently a bug in ui-bootstrap that is fixed in master and will be out soon. I also misunderstood the ui-bootstrap build files and was including both the templated and the non-templated versions in my app.
I monkey patched my ui-bootstrap and switched to templated only and it is now working for me.
see the google group discussion
Angularjs Form showing [object Object] on load in form fields
It occurs only if your form name and ng-model name (value) are same

AngularJS binding json to a form input

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.

Resources