AngularJS Services
How do we share data between controllers?
$scope ?
Requires Nesting
Introduces Tight Coupling
Hard to test
Events?
$broadcast, $emit, $on
https://github.com/angular/angular.js/wiki/Best-Practices
Event Soup
Introduces Tight Coupling
Hard to test
Services?
Services...
- Share business logic
- Lazily Instantiated
- Singleton Objects
- $http, $rootScope...
var exampleService = function(){
var _foo = "bar";
this.getFoo = function(){
return _foo;
}
});
app.service('exampleService', exampleService)
class exampleService
@foo = "Bar"
getFoo: ->
@foo
app.service 'exampleService', exampleService
Service = Singleton
app.controller "exampleCtrl",
($scope, exampleService) ->
$scope.foo = exampleService.foo
class sharedStateService
@foo = "Foo"
app.services "sharedStateService", sharedStateService
Sharing State
app.controller 'firstController', ($scope, sharedStateService) ->
$scope.foo = sharedStateService.foo
$scope.watch('sharedStateService.foo',
(newVal, oldVal, scope) ->
if (newVal != oldVal)
scope.foo = newVal
X2
Interacting with external API's
class httpWrapperService
@inject: ['$http']
$http = null
constructor: ($http) ->
$http = $http
getAll: ->
promise = $http.get('url/of/resource')
return promise
app.service 'httpWrapperService', httpWrapperService
Interacting with external API's
api.controller 'httpGetController',
($scope, httpWrapperService) ->
# Call .getAll() on controller
# initialization
httpWrapperService.getAll().then (response) ->
$scope.all = response.body
State + External API's
class httpStateService
@inject: ['$http']
$http = null
constructor: ($http) ->
$http = $http
@observerCallbacks = []
getAll: ->
promise = $http.get('url/of/resource')
promise.then (response) =>
@all = all
@notifyCallbacks()
return promise
registerCallback: (callback)
@observerCallbacks.push callback
notifyCallbacks: ->
angular.forEach @observerCallbacks, (callback) ->
callback()
app.service 'httpWrapperService', httpWrapperService
State + External API's
api.controller 'httpGetController',
($scope, httpStateService) ->
updateAll = ->
$scope.all = httpStateService.all
httpStateService.registerCallback updateAll
httpStateService.getAll()
Services!
...Factories?
A Factory returns a reference to the function.
A Service returns a single instance of that function
class factoryExample
constructor: (@foo) ->
app.factory 'factoryExample', factoryExample
class serviceExample
@foo = "Bar"
app.service 'serviceExample', serviceExample
app.controller 'exampleController',
($scope, serviceExample, factoryExample) ->
# you create new factories...
fooCreator = new factoryExample("Baz")
$scope.localFoo = fooCreator.foo
# ... and you refer to a single service.
$scope.sourceOfAllTruth = serviceExample.foo
class factoryServiceExample
constructor: (@foo) ->
newService = new factoryServiceExample("bar")
app.factory 'factoryExample', newService
Why Services?
Encapsulates business logic
Provides clean interface to external API's
Shares state between related controllers
...and they're Testable
http://nathanleclaire.com/blog/2014/04/12/unit-testing-services-in-angularjs-for-fun-and-for-profit/
https://docs.angularjs.org/guide/services
http://stackoverflow.com/questions/15666048/service-vs-provider-vs-factory
http://nathanleclaire.com/blog/2014/04/12/unit-testing-services-in-angularjs-for-fun-and-for-profit/
Additional Reading:
AngularJS Services
By Alex Jarvis
AngularJS Services
How do we share information between controllers in AngularJS?
- 931