Why are angular services Singletons? - angularjs

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.

Related

Ionic/angular provider/service - singleton - single instance?

I have read that service(angular)/provider(ionic) can be specific to components, or can be shared by components by registering it at module level. I understand that this is singleton concept that is single instance shared by all components. My question is - suppose the service/provider has code that fetches data from db based on logged in userid, then in this case, how does a single instance concept differentiate between all users using the app? Bit confused on this aspect.
As far As i know singleton means a single component/service that have content that can be shared with any other page/component/controller/...
but all that is happening in one instance of the app.
Example:
lets say in our project we have 3 pages with controllers: page1.html, ctrl1.js, page2.html, ctrl2.js, page3.html, ctrl3.js
We also have 1 service: service1.js
In service1.js we have a function called getUserName()
The concept of singleton will allow getUserName() to be called from all 3 controllers. if the service is not sigleton this means it will be related to one controller/page, so if service1.js is only related to ctrl1.js, the function getUserName() cannot be called from ctrl2.js
Important: all this is happening in one instance of the app, singleton does not mean that the service is SHARED between all running instances of the app.
That being said, if you are using your service to get data from the database based on some parameters, it is the logic you implemented that decide what data will be returned.

AngularJS (with Material) and data exchange between controllers - $rootScope, factory or service

I'm new to AngularJS (currently using 1.6.5) and I'm trying to figure out how to split code from one big controller into couple small controllers which will exchange data between themselves.
In a few words I have the logic to register attendees, register contact person and then credit card capture informations in one large controller (let's call it RegistrationCtrl) as all captured data from those three steps are passed further as the JSON object. My goal is to split that big controller into three separate. Side note - for the attendees registration I'm using mdDialog from AngularJS Material.
I have done some research and I have found multiple ways to do that by using $rootScope or factory, or service.
For the service scenario I thought it is good to share access to the data between controllers like DB or REST API calls somewhere else but not to exchange captured data on a local level between controllers.
$rootScope I'm using in the MainCtrl controller to store data from the DB which I have got via service.
As there are three different ways to handle desired functionality which one I should to choose to have it used in the most efficient way (and will work with AngularJS Material)?
I'm kind of stuck on a decision which one way I should to go. Any suggestions will be helpful.

In angular how do i share data on a session basis

So my understanding is that factories are singletons so any stateful data for a session would be ill placed here.
My next point of call was a service which returns a new instance of the service when injected however I am unsure how I would share one instance of the service to multiple controllers.
Is this an accepted way to solve this issue or does angular provide a better way?
My current use case is that I have a view with some partial views (each partial has it's own controller) and a modal window which takes in a row id and will display data dependant on that data.
I need to be able to share a instance of the service (or equivalent) across these controllers but on a per session basis.
How is this best done?
The singleton exists for one user and loaded SPA. Thats what you would usually refer to as a session. Its a good place to store data that needs to be accessed by different controllers.

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

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.

AngularJS data model architecture approach

I'm new to AngularJS and having a hard time wrapping my head around the conceptual model.
Let's say I want to have an object hierarchy to model a stash repository: Projects contain Repositories contain Tags. Do I create one app, one module and multiple controllers? (Can a module have multiple controllers?) Separate app per object type? Separate module per object type?
All the various data types will be populated by making REST API queries. Read-only for now. Does that change things?
Also, why are they called controllers? They seem to be models. As far as I can tell the controller is actually the AngularJS plumbing.
Here is my rather simple explanation:
A module is just simply a container for all the bits and pieces of your app (services, controllers, directives, filters etc).
Your application may contain different modules - some that you wrote and other third party ones, such as ngGrid for example.
You define a module like this:
var myAppModule = angular.module('myApp', []);
A controller is where the business logic of your application resides. The controller may handle the model, but it is not the model.
The AngularJS documentation for controllers states:
Use controllers to:
Set up the initial state of the $scope object. Add behavior to the
$scope object.
I break up my controllers in to the logical functions that they are supposed to handle. For example, I've written an app to help with combat tracking in a tabletop RPG. I have a controller that handles martial combat and another that handles magick. I also have another controller that helps with the characters. All these controllers are part of my combat app.
I only have one service that is responsible for querying a REST API to retrieve stats and results from a database.
The AngularJS documentation has improved a lot recently and I would recommend reading through it to give you a rough idea of how things work together!
In your example, I'd have a separate controller for each of Projects, Repositories and Tags. I'd have a service to query your datatypes. These would be grouped as part of one module/app.

Resources