Who's responsibility to call $http? Service or Controller? - angularjs

As a backend developer I am little bit struggling with Angular UI MVC concept.
I am trying to draw parallels to my backend MVC so I can understand mindset behind Angular better.
On my backend I have services talking to repositories(or DAOs (Data Access Objects) how we called them in past), controllers calling services to do the job(as they only transport data and not do heavy lifting) and talk to the client(ie browser) and my Model is a combo of(DTOs (Data Transfer Objects) and Entities as of ORM).
As I am inherently inspired by having backend only ever to return/accept JSON(big no to JSP,FreeMarker,Velocity and all others which make my testing life so hard). I would say that on my backend I only have Model-Controller. From the backend perspective my View is AngularJS as JSON data I return could be labelled as part of my Model but it is definitely not my View.
Now when I start to think about UI MVC as of AngularJS I don't understand who should use $http service to talk to backend. The endless examples scattered across the web do not help me. They are either too minimalist or don't show the usage of $http in the full context(simply called from controllers).
I could argue easily for both.
Case A: If AngularJS treats backend as Model then it is the responsibility of angular's services to call $http to talk to backend to retrieve/post data. Here angular controllers still act as basic transport between View and Model ocassionally calling services to get and process data from backend.
Case B
I could also say, hold on - "no", if angular's controllers role is solely to transport then they should get data from backend and deliver to required destination i.e. angular's service/view(if no further processing required).
So which one is "right"? Or at least widely accepted by UI/fullstack devs?

Controllers should only be connecting data and logic with the view and in the most minimal way possible. A bulky controller suggests that either the view needs to be divided up or logic needs to be abstracted into services. $http calls definitely belong in services. The controller doesn't care how the data comes, just that it comes. So:
// controller doesn't care how
getData().then(function(data) {
VS:
// controller is too concerned with "how"
$http.get('/the/path').then(function(data) {
It is typical to see $http calls in controllers in sample code, but not in professional production code.

I would strongly suggest Case A: having this in a service.
Think of Angular controllers as owning each specific piece of view they are assigned to, with services providing ready-made functionality for those controllers.
Also note that a single page can have many views, each of which could be bound to its own instance of a given controller. So it doesn't really make sense to have $http-based functions etc being instantiated a bunch of times. For a service, it will be instantiated once and then shared across any controller that injects it. This is also a great way to share data between controllers, and is one of the strongest reasons to use a service for any given task.

One other suggestion is that thinking of Angular as MVC can lead to issues. Angular is flexible enough to follow multiple design patterns, hence the MVW (Model View Whatever) moniker, but the majority of applications I have seen tend to follow the MVVM pattern. For this reason I would say that the controller should never have knowledge of $http in most cases.

Related

Is a service a model in Angular?

I create a project structure of a web-app with angular.
I create my directories with services, controllers and views.
Then, my team ask me: where are the models? (Nobody of us have worked with angular)
And I answered that in the service, because is where the data persist.
But Im no really sure, and I cant find useful info about this.
What you are looking for is a factory provider. You can create a factory with a collection inside, and this "class" has operations to handle the collection and sincronize it with the back-end.
See this example:
https://github.com/AngularClass/angular-websocket/blob/master/README.md
You can see how to create a collection and initialize it with data that comes from a websocket.
Aditionally you can create operations to handle the collection
This could be consider a "model" in angular.
It is a best practice to keep business logic in Services (and not in controllers, for example). This is, among other reasons, because controllers are instantiated for each view and Services are singeltons.
You can refer to those great posts for more details:
https://johnpapa.net/sharing-data-in-an-angular-controller-or-an-angular-service/
http://teropa.info/blog/2014/10/24/how-ive-improved-my-angular-apps-by-banning-ng-controller.html
https://toddmotto.com/rethinking-angular-js-controllers/
I'm going to assume from the verbiage you've used that you're referring to Angular 1.x.
Services are typically used by controllers to pull data from a provider not displayed in the view. The provider can be a public api, a static file on your own server, a mongo database, etc.
A model for a controller represents the data being manipulated between the view and the controller (refer to ngModel).

datacontext in johnpapa angularjs

In a recent project, we opted for johnpapa angularjs framework for a web app. Now, we want our pages to interact with web api located on the server. So, for this I have googled a bit and found that there are two approaches one is factory and other is service. And the datacontext located in johnpapa angularjs framework is a factory. So, now it looks like that all the calls we going to make to our webapi's needs to be implemented in teh datacontext factory. Which seems little messy imo. And what I want is to create a seperate file for each service/factory i.e. userSvc.js, orderSvc.js
So, is it a good approach to split the functions in different service/factory according to their logical separation. And, second thing is that do i need to create service or factory for calling webapis.

Angular JS - providers vs controllers

Why do we need services or factories, we can also do the same thing by making a normal javascript function, or writing the logic in the controller itself.
For example, when i get json data from the server using '$http.get', i can do it by writing a separate service for it but why is it even required when we can directly write its code in the controller?
This is a good question to ask for clarification before digging into Angular as understanding the parts will enable you to write good Angular code and not just do something because you can.
http://i.stack.imgur.com/BKl1Y.jpg
This is a good visual for Angular as an MVC.
The simple answer to your question is that services should be passing information through your controllers to your various pages and routes. All information logic shared across these views belongs in the service. Controllers pass along that information from the view to the service and from it. Information and logic local that view that doesn't need a broader scope can stay in the controller. This is the clean separation that makes Angular a strong framework.

Why are angular services Singletons?

I am trying to understand singleton pattern.
I write a lot of code in angular and recently I wanted to refactor some of my code and move it to a common place which can be shared by different controllers.So I moved all common utils to my services.
Now the documentation over here says that angular services are singletons but I want to understand the reason behind having singleton pattern here ? Why not have multiple instances of the service object instead of passing references to controllers ?
It all falls in the name "Service". Service, acts like a medium to communicate between controllers or even directives for that matter. Not only for communication, you can add a set of utility functions in your service, which can be used throughout the module/app. This does not need to have multiple instances to serve the purpose. Hence, singleton.
Angular services are the recommended way to exchange data and communicate between controllers. In order therefore to allow this data exchange, services are singleton objects which means that you are guaranteed to have the same service reference between all your controllers.
As an example, imagine that you have an Angular application that displays a list of messages received from another user in the center of the page, as well as the number of received messages or new message notifications in the header. The header and the page content will most probably be under different scopes and be handled by different controllers. In order for these two controllers to have the same view of messages received and be able to display them consistently they will need to use a singleton object holding this information. This object is an Angular service.

What are models in AngularJS?

I don't really understand what a model is in AngularJS. I know what a model is in the context of an MVC framework. For example in PHP I would create a model, like ApiModel.php or something like that, and in there I would put all sorts of cool stuff for the controller to work with.
This doesn't seem to be the way AngularJS thinks of models, in fact I can't find any good explanation of how to implement a model in AngularJS, but everywhere talks about them.
What is a model in AngularJS and how do I use them in the traditional MVC way?
A model in AngularJS specifically communicates with its associated views and controllers and notifies it whether there is a change in its state.
A more thorough description of what is a model can be found in the following link:
https://web.archive.org/web/20140502052028/http://www.webdeveasy.com/angularjs-data-model/
This article is relevant to your inquiry.
More specifically, he mentions that
Model classes encapsulate your application’s data and provide an API to access and manipulate that data. The other classes in your application will make requests of models via this API. When data on the model is updated, the model dispatches events that the other classes within your application can react to. Models are appropriate for capturing the domain logic, such as performing calculations or other manipulations.
A model is just the data that your application consumes.
If the data needs to be dynamic (i.e subject to CRUD operations) you would get this data from a remote source like a database (or even a flat-file) using angularjs' $http in a service or factory and then pass it to the Controller.
If you have a small app for read-only data, then you can hard-code it directly into a Controller.
The most popular data format for angularjs applications these days is JSON because of its flexibility.
The view (or front-end) would then access this data that lives on the scope in the Controller using ng-bind or ng-model or interpolation {{...}}

Resources