Why use a cache - angularjs

In AngularJS you can create a cache.
This is essentially nothing more than the equivalent of an ArrayList<T> in Java where you can add/remove items. In Javascript though, you have push and pop to add/remove stuff from an array.
So why would you want to use AngularJS' cache?
https://docs.angularjs.org/api/ng/service/$cacheFactory

You do it for the purpose of reuse and abstraction.
The cache will only exist once, but if you implement it in every controller or service, you are duplicating the same code over and over, making it harder to maintain.
It's also an abstraction, you are basicly creating a module with an interface, which makes your services independent from the implementation behind it.
In example, you could have a cache item that expires, you could either a write the code/logic to remove the expired ones in every single service, or you could have it in a single module you call cache. This way you are reusing code, and making it easy to maintain.
Wether you use theirs, or make your own doesn't matter, the principals are the same.
One reason to use the Angular cache, is so that you don't have to write the same boiler plate everyone else have already implemented a thousand times. You can go straight to your domain and business logic
You also get certain benifits from using a Cache Module.
You don't have to care about the implementation behind the interface. (Program against an interface, not an implementation).
You can inject a different module with different logic behind it, but with the same interface, with DI.
It's easy to maintain.
You can easily extend and expand it, eg. add expiration.
It's easier to make test stubs (see point 2.).
You can easily reuse the module.
The logic is in it's rightful place, and not scattered around.

Related

Is there a reason to encapsulate if I am the only one using my code?

I understand that we encapsulate data to prevent things from being accessed that don't need to be accessed by developers working with my code. However I only program as a hobby and do not release any of code to be used by other people. I still encapsulate, but it mostly just seems to me like I'm just doing it for the sake of good policy and building the habit. So, is there any reason to encapsulate data when I know I am the only one who will be using my code?
Encapsulation not only about hiding data.
It is also about hiding details of implementation.
When such details are hidden, that forces you to use defined class API and the class is only who can change it inside.
So just imagine a situation, when you opened all methods to any class interested in them and you have a function that performs some calculations. And you've just realized that you want to replace it because the logic is not right, or you want to perform some complicated calculations.
In such cases sometimes you have to change all the places across your application to change the result instead of changing it in only one place, in API, that you provided.
So don't make everything public, it leads to strong coupling and pain during update process.
Encapsulation is not only creating "getters" and "setters", but also exposing a sort of API to access the data (if needed).
Encapsulation lets you keep access to the data in one place and allow you to manage it in a more "abstract" way, reducing errors and making your code more maintainable.
If your personal projects are simple and small, you can do whatever you feel like in order to produce fast what you need, but bear in mind the consequences ;)
I don't think unnecessary data access can happen only by third party developers. It can happen by you as well right? When you allow direct access to data through access rights on variables/properties, whoever is working with that, be it you, or someone else may end up creating bugs by accessing data directly.

What is the advantage of using AngularJS dependency Injection? [duplicate]

I have been working with Angular for some time now, and I fail to see how it is an improvement from my previous way of coding.
First, I can't see what's wrong with having a central object to hold your project. After all, the injector is a singleton that looks up your dependencies into a central place, so Angular does have a central object, it's just hidden. Namespacing doesn't necessarily mean coupling, if it's done properly. And even when it's done, you don't need every single object of your code to be loosely coupled with the others. Besides, anytime you create a standalone JS script, you have to wrap it into Angular to make them play nice together.
Second, it's very verbose to declare all your dependencies everytime (especially with minification), so there is no gain from the readability point of view compared to proper namespacing.
Third, the performance gain is minimal. It forces me to use singletons everywhere, but I can do that on my own if I need to, and most of the time, I don't (network and DOM manipulations are my bottleneck, not JS objects).
In the end, I like the "enhanced" HTML and the automatic two-way bindings, but I can't see how the injection makes it any better than the way other frameworks deal with dependencies, given that it doesn't even provide dynamic loading like require.js. I haven't see any use case where I say to myself "oh, this is where it's so much better than before, I see" while coding.
Could you explain to me what benefits this technical choice brings to a project?
I can see only one for now: convention and best practice enforcement. It's a big one to create a lib ecosystem, but for now I don't see the fruit of it in the Angular community.
For me there are few aspects of how Angular's dependency injection is improving my projects, which I will list here. I hope that this will show you how OTHERS can benefit from it, but if you are well organised and experienced JS developer, then perhaps it might not be the same case for you. I think at some point this is just the matter of developing your own tools and coding guide.
Unified, declarative dependency resolving
JS is dynamic language (that's new, huh?) which gives a lot of power and even more responsibility to the programmer. Components can interact with each other on various ways by passing around all sorts of objects: regular objects, singletons, functions, etc. They can even make use of blocks of code which were not even mentioned to be used by other components.
JS has never had (and most likely never will) a unified way of declaring public, private or package (module) scopes like other languages have (Java, C, C#). Of course there are ways of encapsulating logic, but ask any newcomer to the language and he will simply don't know how to use it.
What I like about DI (not only in Angular, but in general) is the fact that you can list dependencies to your component, and you are not troubled how this dependency got constructed. This is very important for me, especially that DI in Angular allows you to resolve both kinds of components: these from the framework itself (like $http), or custom ones (like my favorite eventBus which I'm using to wrap $on event handlers).
Very often I look at the declaration of a service and I know what it does and how it does it just by looking at dependencies!
If I was to construct and/or make use of all those objects deep in the component itself, then I would always have to analyze implementation thoroughly and check it from various aspects. If I see localStorage in dependencies list, I know for the fact that I'm using HTML5 local storage to save some data. I don't have to look for it in the code.
Lifespan of components
We don't need to bother anymore about order of initialization of certain components. If A is dependent on B then DI will make sure that B is ready when A needs it.
Unit testing
It helps a lot to mock out components when you are using DI. For instance, if you have controller: function Ctrl($scope, a, b, c, d) then you instantly know what it is dependent on. You inject proper mocks, and you are making sure that all parties talking and listening to your controller are isolated. If you have troubles writing tests then you most likely messed up levels of abstraction or are violating design principles (Law Of Diameter, Encapsulation, etc.)
Good habits
Yes, most likely you could use namespacing to properly manage the lifespan of your objects. Define singleton where its needed and make sure that noone messes up your private members.
But honestly, would you need that if the framework can do it for you?
I haven't been using JS "the right way" just until I learned Angular. It's not that I didn't care, I just didn't have to since I was using JS just for some tweeks of UI, primarly based on jquery.
Now its different, I got a nice framework which forces me a bit to keep up with good practices, but it also gives me great power to extend it and make use of the best features that JS has.
Of course poor programmers can still break even the best tool, but from what I've learned by recently reading "JS the good parts" by D. Crockford people were doing reeeeeealy nasty stuff with it. Thanks to great tools like jQuery, Angular and others we now have some nice tool which helps to write good JS applications and sticking to best practices while doing so.
Conclusion
As you have pointed out, you CAN write good JS applications by doing at least those three things:
Namespacing - this avoids adding stuff to global namespace, avoids potential conflicts and allows for resolving proper components easily where needed
Creating reusable components / modules - by, for instance, using function module pattern and explicitly declaring private and public members
Managing dependencies between components - by defining singletons, allowing for retrieving dependencies from some 'registry', disallowing of doing certain stuff when certain conditions are not meet
Angular simply does that by:
Having $injector which manages dependencies between components and retrieves them when needed
Forcing to use factory function which has both PRIVATE and PUBLIC APIs.
Let the components talk to each other either directly (by being dependent of one another) or by shared $scope chain.

AngularJS: same logic but different HTML forms & database for different projects/clients

The app which I am developing will have the same functionality for all users/clients/projects (call 'em what you will).
However, the HTML forms presented to the user and the AJAX used to send them to the server will vary for each project.
I was thinking of using Angular constants, with ng-show / ng-hide (maybe even ng-if) on the HTML and a switch in the controller, based on a constant for the AJAX send & receive.
Is this a good approach? I can see things getting complex with more than a handful of projects. Should I use a different view/controller for each project? I might lose out on some common code that way, but it's less likely t become spaghetti.
I would suggest taking a domain/(test) driven approach. Don't generalize too much code up front.
Building generalized code will create dependencies that are all a potential victim in need of future refactoring. Even in the case of simple changes. Nothing is more time consuming / frustrating than those small modifications that cause an avalanche. I've seen alot of projects run out of time because the code base was over engineered at the start.
My approach, especially for the more complex projects with no clear overview of overlapping functionalities, is to just start designing/building the functionalities separate of each other in small steps. Just like any agile workflow, deliver a complete working feature (a working form) and when you're working on feature and notice that there's a shared functionality build earlier on, make a (wise) decision to refactor/promote the existing code into generalized code. At this stage you'll be in a better position to make such a judgement. If you've taken the test driven approach (which I highly recommend) refactoring the existing code can be done without too much effort.
Working this way gives a greater guarantee to deliver and to end up with good readable optimised code.
TL;DR
It all comes down to common sense.

Angular controllers: 1 per view - does it make sense?

I have been thinking about this lately. Up until now I have always subscribed to John Papa's recommendation which can be seen here:
https://github.com/johnpapa/angular-styleguide#controllers
Define a controller for a view, and try not to reuse the controller for other views. Instead, move reusable logic to factories and keep the controller simple and focused on its view.
He gives a reason that I don't understand but for me it was primarily motivated by ease-of-work/maintainability. Basically, in working on large applications, it really sucks to come upon a bloated controller that is responsible for several disparate views. If a developer wants to clean up the controller, he/she has to go to each view and determine what is being used and why (so that methods can be consolidated if they are very similar) which is a big job. Typically (especially if they are under time constraints), they choose to just add whatever functionality they need to the model and to "come back to it later" which is how it got bloated in the first place. Also, I have always used the controller/directive as an indication of whether logic is repeated in many views or not (i.e. if another developer walks up to a controller that I have written he/she can be sure that I have only used it with one view because otherwise it would be directive).
This is a similar problem to the endpoint-problem which basically has people adding endpoints on an as-need basis and the eventually due to new people not knowing about old endpoints or simple forgetfulness the API gets super bloated and repetitive.
However, as I said, recently I have been thinking that this 1-1 controller to view relationship really works against the entire MVC pattern because it couples the model to the view and destroys the separation of concerns. I mean, as long as a controller stays focused (i.e. we have an EditUserCtrl whose job it is to edit a user etc.) then why shouldn't two views be able to use that controller? I mean if the business decides it needs a new view in another place that has the same function, why shouldn't I just write a new view and hook it up to the old controller? I guess what I am saying is that I am having trouble reconciling a convention that goes against the fundamentals of a framework.
Would love to hear others thoughts on this. Thanks in advance.
Like you said yourself. If a controller is responsible for more than one view, any developer can walk up to it, change something in the hopes of adding new functionality to view A and not even knowing it's breaking view B. I think the primarily goal would be to keep controllers clean and neat. That way, it's best to have 2 controllers almost identicals, but with only 2~3 line of codes than to have files being referenced by a numerous number of other files that nobody has control over it.
At one hand, you have to change 2 controllers if something drastically changes in view A and view B, but if it's a complex task, you'll probably have the controllers calling some sort of Gateway and that might mean that you won't have to change any of the controllers at all (good outcome).
On the other hand, if you have 10 different views repeating the same 2~3 lines of code, maybe it's time to abstract the controller functionality.
It doesn't couple the model because the it's best practice to have the business logic in services and view logic in directives , and have there be no real logic in the controllers. So you can one controller per view, but that controller should be very skinny. Personally, I like to only use controllers to assign and communicate variables between services and directives. If you want to reuse controller code, what's stopping you from either putting that logic in directives and services?
Almost none of the controllers I write (and for my job I write a large enterprise application in angular) have logic in them. Granted sometimes logic in controllers is unavoidable, but try to keep as little as possible there.
In this way, the controller stays focused. For a large application, with, say, 10 pages, it's better for both usability and readability to have small controllers for each page instead of one giant controller with a mix of variables, and when you want to re-use methods and functions, put them in services. If you find yourself having three pages with a form or button that has the exact same logic, then that might be better served with a custom directive.

What are the benefits of AngularJS dependency injection?

I have been working with Angular for some time now, and I fail to see how it is an improvement from my previous way of coding.
First, I can't see what's wrong with having a central object to hold your project. After all, the injector is a singleton that looks up your dependencies into a central place, so Angular does have a central object, it's just hidden. Namespacing doesn't necessarily mean coupling, if it's done properly. And even when it's done, you don't need every single object of your code to be loosely coupled with the others. Besides, anytime you create a standalone JS script, you have to wrap it into Angular to make them play nice together.
Second, it's very verbose to declare all your dependencies everytime (especially with minification), so there is no gain from the readability point of view compared to proper namespacing.
Third, the performance gain is minimal. It forces me to use singletons everywhere, but I can do that on my own if I need to, and most of the time, I don't (network and DOM manipulations are my bottleneck, not JS objects).
In the end, I like the "enhanced" HTML and the automatic two-way bindings, but I can't see how the injection makes it any better than the way other frameworks deal with dependencies, given that it doesn't even provide dynamic loading like require.js. I haven't see any use case where I say to myself "oh, this is where it's so much better than before, I see" while coding.
Could you explain to me what benefits this technical choice brings to a project?
I can see only one for now: convention and best practice enforcement. It's a big one to create a lib ecosystem, but for now I don't see the fruit of it in the Angular community.
For me there are few aspects of how Angular's dependency injection is improving my projects, which I will list here. I hope that this will show you how OTHERS can benefit from it, but if you are well organised and experienced JS developer, then perhaps it might not be the same case for you. I think at some point this is just the matter of developing your own tools and coding guide.
Unified, declarative dependency resolving
JS is dynamic language (that's new, huh?) which gives a lot of power and even more responsibility to the programmer. Components can interact with each other on various ways by passing around all sorts of objects: regular objects, singletons, functions, etc. They can even make use of blocks of code which were not even mentioned to be used by other components.
JS has never had (and most likely never will) a unified way of declaring public, private or package (module) scopes like other languages have (Java, C, C#). Of course there are ways of encapsulating logic, but ask any newcomer to the language and he will simply don't know how to use it.
What I like about DI (not only in Angular, but in general) is the fact that you can list dependencies to your component, and you are not troubled how this dependency got constructed. This is very important for me, especially that DI in Angular allows you to resolve both kinds of components: these from the framework itself (like $http), or custom ones (like my favorite eventBus which I'm using to wrap $on event handlers).
Very often I look at the declaration of a service and I know what it does and how it does it just by looking at dependencies!
If I was to construct and/or make use of all those objects deep in the component itself, then I would always have to analyze implementation thoroughly and check it from various aspects. If I see localStorage in dependencies list, I know for the fact that I'm using HTML5 local storage to save some data. I don't have to look for it in the code.
Lifespan of components
We don't need to bother anymore about order of initialization of certain components. If A is dependent on B then DI will make sure that B is ready when A needs it.
Unit testing
It helps a lot to mock out components when you are using DI. For instance, if you have controller: function Ctrl($scope, a, b, c, d) then you instantly know what it is dependent on. You inject proper mocks, and you are making sure that all parties talking and listening to your controller are isolated. If you have troubles writing tests then you most likely messed up levels of abstraction or are violating design principles (Law Of Diameter, Encapsulation, etc.)
Good habits
Yes, most likely you could use namespacing to properly manage the lifespan of your objects. Define singleton where its needed and make sure that noone messes up your private members.
But honestly, would you need that if the framework can do it for you?
I haven't been using JS "the right way" just until I learned Angular. It's not that I didn't care, I just didn't have to since I was using JS just for some tweeks of UI, primarly based on jquery.
Now its different, I got a nice framework which forces me a bit to keep up with good practices, but it also gives me great power to extend it and make use of the best features that JS has.
Of course poor programmers can still break even the best tool, but from what I've learned by recently reading "JS the good parts" by D. Crockford people were doing reeeeeealy nasty stuff with it. Thanks to great tools like jQuery, Angular and others we now have some nice tool which helps to write good JS applications and sticking to best practices while doing so.
Conclusion
As you have pointed out, you CAN write good JS applications by doing at least those three things:
Namespacing - this avoids adding stuff to global namespace, avoids potential conflicts and allows for resolving proper components easily where needed
Creating reusable components / modules - by, for instance, using function module pattern and explicitly declaring private and public members
Managing dependencies between components - by defining singletons, allowing for retrieving dependencies from some 'registry', disallowing of doing certain stuff when certain conditions are not meet
Angular simply does that by:
Having $injector which manages dependencies between components and retrieves them when needed
Forcing to use factory function which has both PRIVATE and PUBLIC APIs.
Let the components talk to each other either directly (by being dependent of one another) or by shared $scope chain.

Resources