I'm very new to Angular and MV* in general (short of what I've gleaned from watching other devs work with Ruby on Rails for years), so please pardon what's probably a naive question.
I'm trying to set up a typeahead field where users can enter a street address and get live suggestions from the Google Geocoding API. I started verbatim with this example from UI Bootstrap (the "Asynchronous results" example in the middle field):
http://angular-ui.github.io/bootstrap/#/typeahead
It's working locally, but now I want to extend it to gather other pertinent details of the address and submit those along with the other form data. For example, if the Geocoding API returns a country
type in address_components
in its results (example here), I'd like to add that to the form data that I POST to the server. (There will be other logic to how/what properties I need to capture, but that's a good starting point.)
Right now, only the formatted_address
property returned by the Geocoding API is submitted with the form, as the ui.bootstrap.typeahead
directive binds that to the typeahead directive's <input>
using ng-model
.
So, my question is twofold (but please feel free to address either separately):
<input>
bound with ng-model
for every value I might want to capture, and then the controller would handle filling in the ones that are available?.then()
within $scope.getLocation()
, where I'm handling the $http
response, but my gut says that that's not ideal. All I can imagine doing there is adding properties to the form values object that I'm building (i.e., the object I'll POST on form submit), but then I have to know the names of those properties, so now my controller is tied too closely to the form in which it's used.Thanks in advance for any help. I hope this makes sense. Since I'm still grasping the fundamental concepts, it would be especially useful if you could point me to any existing code that does something similar, or refer to specific documentation or articles that could lend some insight.
On #1, the Angular-UI design is a very "Angular" way to implement it - I don't see any issue with it. The directive takes a list and returns the selected list item. This is how the controller sees it. Put it in other words, another directive, say a typical <select>
or a custom infinite scroll or a yelp-style map, would provide a different View behavior, but would be functionally equivalent from the controller's point of view - which keeps the separation of concerns intact, and thus very MVVM-y.
I also think that you have some confusion about ng-model
. ng-model
should be used with input controls (not only <input>
) with which the user interacts with directly. In this case, the only input is a typeahead directive.
On #2, it depends whether the the "other pertinent details" are natural part of the service API or if they need to be fetched after selection. Assuming the former, the correct place is, in theory, in a service. The controller should only marshal data from Services to the ViewModel and back.
For your specific example with the country code, the API returns multiple components in address_components
property. The extraction of the country code - as well as checking if it exists or not and other business logic - is best to handle in a service, probably with another service API after selection, or when the original list of addresses is obtained - whatever makes sense for your case.
For a simple case in a simple app, like in the example, you could just modify the $scope.getLocation()
function to return a list of actual objects that your controller (or rather your ViewModel) actually needs, and then have the View return the selected object (as per #1).