I've recently ran into a factory that vaguely resembles the one shown below:
.factory("MyFactory", ['$interval', function($interval) {
var factoryObj;
factoryObj.setCheckupTime = function(intervalMs) {
var checkupInterval = $interval(function() {
// do checkup logic...
}, intervalMs);
};
factoryObj.setCheckupTime(60000);
return factoryObj;
}]);
The problem is the line right before the return:
factoryObj.setCheckupTime(60000);
This line feels wrong because we're making a singleton perform an action on itself automatically instead of by some dependent unit of code.
I wanted to get others' opinions on the matter; does this go formally go against any of Angular's best practices, or maybe any rules on how Singletons are supposed to be used?
I was also unsure how to describe this problem as I've never ran into it; is there another term/terminology for what's going on here?
So, is it a bad idea declaring a factory that self starts it's own thing when it's built by angular's core not telling anybody that something has started in the process?
Yes, that's really bad! Is really difficult to maintain and track problems when things are done automatically especially on angular factory that is an internal behavior.
I recommend starting it manually from somewhere that you can track and understand it in the future.
Related
I was learning angular. i didn't get anyhitng from angular documentation can anyone please tell me what is $watch
what does it happens if we change that to $scope.$watch
sorry i'm new to the anguar this question seem like bit silly....if i'm wrong in knowledge
There is not stand alone $watch service. People are saying $watch instead of $scope.$watch but it's the same. it's just longer to say $scope.$watch, and it's just to mention that even if it's related to $scope he's like a whole new service.
But I may be wrong there's maybe an external stand alone service who's name is $watch, but I don't think so.
if you watch an expression, you need a context that is used to resolve it. Consider
$watch("foo", handler);
how should angular know what foo to watch? It makes only sense in the context of a scope
somescope.$watch("foo", handler);
so angular know what foo to watch.
But if you are talking about watches in general, many people omit the scope for the sake of simplicity. But you should know: You can't watch for something if you don't know where to watch ;)
I have this situation now where I’ve implement models as a plain JavaScript object. So you can synchronously ask the model for a value and you can subscribe to event to get notified about updates to the model. But I’m not happy doing it this way. It leads to a lot of code and checks everywhere.
Now, I’ve been thinking, wouldn’t it be better to make use of Angular and use isolated scopes for the models? This way anyone interested in a particular value can just watch the model for changes.
Example:
function UserService($rootScope) {
var model = $rootScope.$new(true);
this.getModel = function() {
return model;
};
}
function userWidget(userService) {
var user = userService.getModel();
user.$watch('isLoggedIn', function(isLoggedIn) {
//React to if the user i signed in or not...
});
}
Is it a good idea or a bad idea? Any thoughts about this? How have you solved this?
Even if silly, here is a small demo:
http://plnkr.co/edit/JTggQ0FVYpo4saLmjLAo
Thanks!
/Martin
There's nothing wrong with it, but I would personally have a benefit to describe before I just randomly did that. $rootScope.$new is actually sort of heavy - an AngularJS scope has a lot of additional reference objects like siblings and parents. If you have 5, who cares? But if you have 5,000 that's going to be heavy for the garbage collector to manage. It's totally justified if it gives you some advantage, but if it's just for the sake of itself I wouldn't bother.
Is there a reason you rely on variable hoisting so much in your example? It's usually viewed as a by-product or anti-pattern, so it may throw off other developers who help maintain your code. Or are you flying solo? :)
In my foray into AngularJS, I've been a little confused. The main reason for this, is because I never really quite understood, what the model part of the whole thing was. I mean, its a MVC framework, so it had to have models, correct? So, I did a little bit of reading on the matter. I tried reading this bit of documentation, here.
What I understood from that was, that the model aspect of the controller, what in fact what was inside the $scope dictionary. Fine, and this did not bother me, until I read a blog post by evil-trout, one of the makers of discourse.
What he was trying to get by, was that Angular did not have a proper modelling scheme. I tried looking into SO for answers, and I bumped into this. This was a good read, but really did not give me concrete examples of how to structure models in AngularJS.
I've felt that this was indeed lacking since, I'm used to django development, and having clear models is helpful. In emberjs, there seems to be a way to make models, that inherit from an Ember class. Also, after reading evil-trout's blog post, I understand the potential pitfalls of having all variables attached to the scope, and many of them being primitives, and not objects.
So, what is the best way to structure a model in AngularJS, such that you can have maintainable code in the future. The main reason I stick with angular is because it is wonderfully simple to write, but I fear that it might end up being something like php, where functionality has often been supplanted for the sake of simplicity.
I hope I've been able to make my question clear, if not then please feel free to leave a comment, telling me how I can improve.
Things to remember about models
They represent a chunk of data...
That chunk can come from an API, a static file, be explicitly declared.
It can be updated by events in your app.
They can be many or one...
A model does not have to be an all encompassing object. If you see potential for abstracting smaller models from a single model, you have discovered modular code. Injecting child services into your parent ensures a separation of concerns and re-usability.
A good example here is think about a service that consumes two API's to build a single model. You could certainly build it like this:
angular.module('things', [])
.factory('Things', function($http) {
var _things = {};
_things.getThing1 = function(){return $http.get('http://ONE.com/1')};
_things.getThing2 = function(){return $http.get('http://TWO.com/2')};
return _things;
};
But what if you want to use those API calls in another project? Are the components that make up my single service really best represented as their own services?
angular.module('thing1', [])
.factory('T1', function($http) {
var _thing1 = {};
_thing1.getThing1 = function(){return $http.get('http://ONE.com/1')};
return _thing1;
};
angular.module('thing2', [])
.factory('T2', function($http) {
var _thing2 = {};
_thing2.getThing2 = function(){return $http.get('http://TWO.com/2')};
return _thing2;
};
angular.module('things', ['thing1','thing2'])
.factory('Things', function(T1,T2) {
var _things = {};
_things.getThing1 = T1.getThing1();
_things.getThing2 = T2.getThing2();
return _things;
};
Now you can use thing1 or thing2 independent of things. Which is great news, because the next project you are working on doesn't need thing1 but definitely needs thing2. If nothing else, modular services (or any code in general) will give you structure to your app that will help you identify things as components rather than blobs.
We have been using Angular for some time now and we have come up with a convention that helps us in keeping scope pollution under control.
We define at max 2 properties on the the $scope variable in every controller. viewModel and model. The viewModel being a object which helps us in achieving easy model binding and the model object which is the data pertaining to the view for CRUD operations.
We follow this convention across main view (ng-view),sub-view (view created with ng-include), directives (if we create isolated scope).
Shameless plug: I wrote a blog post detailing this just few days back :)
First of all I must admit I am quite new to Angular.js and I haven't used any new generation js framework like Backbone or Knockout before. I'm creating an application which communicates with server using RESTful API. I dug a lot into angular documentation and blog notes so as I could do it right.
I found examples mostly with $resource. It looks pretty good: many built-in methods, when you design your REST interface properly you don't even have to write anything more.
But I (and my whole team too) are more used to JavaEE way of thinking about model layer: lightweight model classes (POJO, etc), DAO classes persisting and fetching model and optionally service layer between DAO and controllers. On the other hand in Angular $resource creates something more resembling active record.
I've already come up with two ways how to implement DAO pattern in Angular:
Writing everything from scratch, going down to the $http abstraction level. I'd implement every DAO method as $http call, take care about errors.
Using $resource objects normally like lightweight model classes and passing them to DAOs which are the only unit responsible for calling actions like .$save() on them. Of course we cannot prevent calling it in different place, but solution with such convention is good enough for me.
Second way looks better for me because of reusing existing code. $resource has nice behaviour of promise object and I will be happy if I don't have to implement it myself.
So finally the main question: is active record approach is the only way of doing data access right in Angular, Backbone and other tools like that? Maybe somebody have already tried to incorporate similar solution more resembling DAO in his code and can share his thoughts about it?
And the second question: is $resource object sufficient when it comes to dealing with errors, connection losses and different problems? Is it worth to use $resource having this in mind or it's better to start with lower level $http.
I am at the beginning of the project and I know that this decision may well affect the whole project life later, so I want to choose the best.
I totally agree. Here is the way I do it:
bankApp.factory("CustomerRepository", function ($resource) {
var customerRepository = $resource("rest/customers/:id", {id:'#id'}, {'update': {method:'PUT'}});
// You can also add addition repository like $http calls onto the
// customerRepository like getting the count and other stuff.
return customerRepository;
});
Then you can inject the CustomerRepository where ever you need it. For example:
bankApp.controller("BankController", function ($scope, CustomerRepository) {
$scope.customers = CustomerRepository.query();
$scope.createCustomer = function () {
CustomerRepository.save($scope.customer, function (customer) {
...
});
};
...
$scope.saveCustomer = function () {
CustomerRepository.update($scope.customer, function (customer) {
...
});
};
});
I'm working within a Javascript + BackboneJS (an MVC framework) + RequireJS framework, but this question is somewhat OO generic.
Let me start by explaining that in Backbone, your Views are a mix of traditional Views and Controllers, and your HTML Templates are the traditional MVC Views
Been racking my head about this for a while and I'm not sure what the right/pragmatic approach should be.
I have a User object that contains user preferences (like unit system, language selection, anything else) that a lot of code depends on.
Some of my Views do most of the work without the use of templates (by using 3rd party libs, like Mapping and Graphing libs), and as such they have a dependency on the User object to take care of unit conversion, for example. I'm currently using RequireJS to manage that dependency without breaking encapsulation too much.
Some of my Views do very little work themselves, and only pass on Model data to my templating engine / templates, which do the work and DO have a dependency on the User object, again, for things like units conversion. The only way to pass this dependency into the template is by injecting it into the Model, and passing the model into the template engine.
My question is, how to best handle such a widely needed dependency?
- Create an App-wide reference/global object that is accessible everywhere? (YUK)
- Use RequireJS managed dependencies, even though it's generally only recommended to use managed dependency loading for class/object definitions rather than concrete objects.
- Or, only ever use dependency injection, and manually pass that dependency into everything that needs it?
From a purely technical point of view, I would argue that commutable globals (globals that may change), especially in javascript, are dangerous and wrong. Especially since javascript is full of parts of code that get executed asynchronously. Consider the following code:
window.loggedinuser = Users.get("Paul");
addSomeStuffToLoggedinUser();
window.loggedinuser = Users.get("Sam");
doSomeOtherStuffToLoggedinUser();
Now if addSomeStuffToLoggedinUser() executes asynchronously somewhere (e.g. it does an ajax call, and then another ajax call when the first one finishes), it may very well be adding stuff to the new loggedinuser ("Sam"), by the time it gets to the second ajax call. Clearly not what you want.
Having said that, I'm even less of a supporter of having some user object that we hand around all the time from function to function, ad infinitum.
Personally, having to choose between these two evils, I would choose a global scope for things that "very rarely change" --- unless perhaps I was building a nuclear powerstation or something. So, I tend to make the logged in user available globally in my app, taking the risk that if somehow for some reason some call runs very late, and I have a situation where one user logs out and directly the other one logs in, something strange may happen. (then again, if a meteor crashes into the datacenter that hosts my app, something strange may happen as well... I'm not protecting against that either). Actually a possible solution would be to reload the whole app as soon as someone logs out.
So, I guess it all depends on your app. One thing that makes it better (and makes you feel like you're still getting some OO karma points) is to hide your data in some namespaced singleton:
var myuser = MyApp.domain.LoggedinDomain.getLoggedinUser();
doSomethingCoolWith(myuser);
in stead of
doSomethingCoolWith(window.loggedinuser);
although it's pretty much the same thing in the end...
I think you already answered your own question, you just want someone else to say it for you : ) Use DI, but you aren't really "manually" passing that dependency into everything since you need to reference it to use it anyways.
Considering the TDD approach, how would you test this? DI is best for a new project, but JS gives you flexible options to deal with concrete global dependencies when testing, ie: context construction. Going way back, Yahoo laid out a module pattern where all modules were loosely coupled and not dependent on each other, but that it was ok to have global context. That global context can make your app construction more pragmatic for things that are constantly reused. Its just that you need to apply that judiciously/sparingly and there need be very strong cases for those things being dynamic.