Welcome to Part 2 of this review of the Pluralsight course Angular Best Practices by Joe Eames.
Joe has worked both full and part time as a technical teacher for over ten years.
He has produced 18 courses for Pluralsight.
Writing Controllers & Services
Each of these types of objects plays an important role in an Angular application:
Services are an overloaded term, so Joe gives them a clearer definition here with 4 specific responsibilities of Services.
He also defines the responsibilities of directives and views.
It’s ok to manipulate the DOM from a controller. True or False?
It’s ok to manipulate the DOM from a service. True or False?
Where does busing logic belong?
Minification removes whitespace and shortens variables and parameters. We see a simple app that just outputs “I’m a service!”.
There is a danger of your minifier of choice breaking your app by mangling your variable names.
When $scope is changed, Angular no longer knows what to do with it and our binding no longer works.
To protect ourselves against this we need to “minsafe” our code.
For a simple example of this see http://stackoverflow.com/questions/18782324/angularjs-minify-best-practice
Joe demonstrates ngMin, a Node utility for automatically minsafing a JS file of Angular code, and uses UglifyJS to minify the code.
Joe also shows that ngMin can miss places where it needs to minsafe, and I found on GitHub that ngMin is now deprecated and https://github.com/olov/ng-annotate is recommended instead.
In summary, the options that we have are:
– Don’t minify
– Manually Minsafe
– Use ng-annotate
– Don’t mangle parameter names in the minification process
Joes describes the pros and cons of each.
1. What are the two main benefits of minification?
2. What are the two main methods of minifying code?
3. ngMin wil minify your code safely. True or False?
A controllers responsibilities are:
– Setup the Scope
– Handle View Interaction
It’s code should only enable communication between the view and either the model or services that handle events raised by the view.
We see the basic pattern for creating Angular controllers. Then we see a “slightly odd” way to create them.
Finally we see an older way too define controllers, which has fallen out of favour within the Angular community.
Controllers – Design Guidelines
The controller should only coordinate between the model and the view. We see a scheduleCtrl example of a controller logic anti-pattern and how to refactor it.
Another best practice, which applies to every Angular object, it not to have too many collaborators.
There is no objective answer to what is too many, but Joe recomends evaluating whether you have too many when your get up to 3 or 4.
Again we see an anti-pattern example, this time along with the tell all comment
// kill me now....
One way to control this is using the facade pattern.
We also see an example of a globals.js file, but Joe says this is an insidious dependency.
The last guideline is for all of the controllers to be testable. Fortunately if you follow the previous two guidelines you will typically get this benefit for free.
The responsibilities of Services are:
– Handle non-view logic
– Communicate with the Server
– Hold data & state
We see 5 ways of creating services:
– value function
– constant function
– factory function
– service function
– provider function
Ultimately all of these functions use the provider function to do the “heavy lifting”.
Filters as Services
There is actually one more way to create a service: using filters.
In this lesson we see a list of subjects (Chemistry, Physics etc) along with a filter that displays 5* ratings.
Joe teaches how to programmatically call the rating filter from controller code.
Finally we see that using a factory function works just the same, showing us that filters are just services under another name.
Services – Design Guidelines
The principles covered in this lesson are:
– Single Responsibility Principle
– Loosely Coupled
– Good Interface
The Single Responsibility Principle states that classes should only have one reason to change. We see an AngularJS anti-pattern and learn about the problems associated with too many responsibilities.
A better way is to create a registration service.
A good service is also cohesive: all functionality of an object relates to the primary purpose of the object.
Loose coupling means the dependencies that a service has are not tightly coupled to the service itself. We see policies.canRegisterStudent is loosely coupled, but use of multiple && operators is a sign of tight coupling.
This example is also an example of a bad interface design. Joe also shows a second example of this, and concludes that services should be the meat of our applications and follow all of these guidelines.
Services – Specific Types
This lesson looks at three types of services:
– Stateful Singletons
A factory is just an object which constructs other objects.
A stateful singleton is a service that is an object that contains data and/or state. This is demonstrated using a class registration page.
Services as functions are quite rare, but Joe says they can be very helpful in the right situations. We see that this involves less code than returning an object which contains a function.
1. Is it acceptable for services to be stateful?
2. Name 4 ways to create a service
3. If you pass the service method a constructor function, what will your service be when injected into other services & controllers?