tl;dr
I'm really struggling to find the appropriate pattern here. How should I best configure a generalized provider to a specific use-case? I can't use $http as a dependency in .configure(); can I?
longer, boring explanation:
I am trying to create a generalized provider which I may reuse in Angular. I have it working, however it requires configuration.
The intention is to provide a fallback REST service to use in saving data to the server, but with provision to save offline in local-storage. Therefore, I need to provide appropriate $http calls for each instance of this provider.
Is it possible to provide appropriate $http calls with .configure() or else should I try and figure out how to inject $http into the provider from the start and then configure it afterward??
It's frustrating... and may change in AngularJS 2.0... But for now, yes, it is not possible to do this. There is a very high wall between the .configure() and .run() states, so you can't access $http from a .configure() function. The reason is that it hasn't actually been created. At this stage, all that exists is the provider. Once all of the dependencies are configured, then the http provider will be used to make the real $http service.
I'm not sure exactly what you're trying to do, but there are two excellent AngularJS developers that are good to follow who have some advanced patterns in projects they've shared: Pascal Precht and Brian Ford. Here are two projects that make heavy use of provider/service concepts as well as $http-driven services:
https://github.com/angular-translate/angular-translate
https://github.com/btford/angular-modal
Angular Modal, especially, does $http work to load its templates. There might be use cases in there that are similar to what you're trying to do.
Related
how to access this variable "process.env.endPointAPI" in yeoman
in the factories Services ?
I want to call the API from different server?
To complement my comment to the question and to provide a more detailed answer:
It is necessary more info regarding your code. I guess you are using a yeoman generator with nodejs server side, maybe with expressjs. If that is the case then you need to pass process.env.endPointAPI via express with the help of your templating engine or change your grunt/gulp tasks to include it in a custom angular factory (for example) when you serve/build your app.
This article describes some of these situations step-by-step.
If the options in the article above don't work for you for some reason, and you are using grunt, maybe you can give grunt-ng-constant a try. Basically, it will generate you a custom constant-value utility for Angular. Once injected in your app module you can access those values from your controllers for example.
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.
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.
When expecting a call to the API should I include the entire URL including all the parameters, or do I just need a partial match?
Should I be listening for a call to the exact URL :
http://address.of.api/stuff/123?include=thing,anotherthing.name;
Or do I just need this :
/stuff/123
$httpBackend is part of Angular's Mock environment designed to replace real backend by fake one, or rather by imitating how Angular's $http works without real backend.
As much as I love Angular, I find $httpBackend over-engineered and unnecessarily complicated for what it does:
It is not recommended way to throw complicated code inside your tests. The more you do it, the more chance is that you create errors in that testing code instead of what you are actually supposed to test.
It promotes the bad practice of placing $http (or other low-level services in your abstraction hierarchy) freely around your code, as you can later use that $httpBackend to mock it away.
Instead it works cleaner to isolate any reference to low level methods into dedicated methods of your own, whose single responsibility is to make http requests. These dedicated methods should be able to work with real backend, not a fake one!
More details here on Angular testing
Hi I'm building an angularjs app that has a timer throughout the application. Every minute I will be polling the server to see if a user has gotten a new message in their inbox.
I was wondering what is the best way to design this? I see two options so far:
1.) Rootscope function
2.) A Service
The problem with the service approach is that I have to inject this service to every controller I have. Does anybody else have any suggestions on how to design this app?
Thanks
Use a service - it's a cross-cutting concern that some, but probably not all of your controllers need to know about. Injecting it where it is needed does involve some extra keystrokes at first, but it's a benefit, not a problem - it keeps your code modular and easier to test.
If you use a service, you can inject a stubbed instance into your controller tests so you can test the controllers in isolation. You can use Jasmine spies (for example) to return mock values from your service, so you can easily test how your controllers behave with a range of inputs.