angular.service('$xhr.error', function(loginService) {
return function(request, response) {
console.log(request.url+":"+response.status);
if (response.status == 401) {
loginService.loginRequired(request);
}
};
}, {$inject: ['loginService']});
This service is supposed to handle all the HTTP 401 problems, so it
notifies "loginService", so it can notify a login dialog, login dialog
is supposed to ask for credentials and ask my loginService to
authenticate. When authenticate is successful, all the failed requests
are to be resend. So far so good, but my loginService needs $xhr
service:
angular.service('loginService', function($xhr) {
....
$xhr is needed in login method, so it can send credentials to the server.
....
}, {$inject: ['$xhr']});
The problem here is $xhr requires $xhr.error, $xhr.error requires
loginService and loginService requires $xhr. It looks like <angular/>
does not support circular dependencies of services, does it?
When I open my application in Firefox, it stops responding. Chromium
logs: RangeError: Maximum call stack size exceeded.
Is there any way to walk this problem around?
Thanks,
Witold Szczerba
angular.service('$xhr.error', function($xhr) {
....
}, {$eager: true});
Attaching an example. WARNING: this will crash Firefox (Chromium is
fine, don't know about other browsers). Remove $xhr dependency and
everything works fine.
The real problem is how to introduce XHR error handler which is able to resend.
$xhr.error cannot depend on $xhr, but $xhr does depend on $xhr.error
and this is hard-coded. Traditional approach to break circular
dependencies between "A" and "B":
A --> B, B --> A
is to introduce "C":
A --> C, B --> C and C --> [A,B]
In our case (A is $xhr and B is $xhr.error) the first dependency
cannot be removed:
A --> B (fixed), B --> C, C--> [A,B]
but this is still a circular dependency and will crash in runtime.
I remember Misko was writing about this some time ago, found it:
http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/
Will try to apply that to my problem :)
Regards,
Witold Szczerba
On 3 June 2011 12:55, Witold Szczerba <pljos...@gmail.com> wrote:
angular.service('foo', function(...) {
var scope = this;
return function(...) {
if(should_resend){
var xhr = scope.$sevice('$xhr');
...
}
};
}, {$inject: [...]});
Adam
> --
> You received this message because you are subscribed to the Google Groups "angular" group.
> To post to this group, send email to ang...@googlegroups.com.
> To unsubscribe from this group, send email to angular+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/angular?hl=en.
>
>
Hello,
I have, actually, introduced an event bus concept already. At first I
wanted to create a generic event bus, so anyone interested would
announce "anything" and anyone listening could add a condition and
callback functions. Then I changed my mind, because such a service
could become a global context of entire application, anyone would
declare dependency on it and I was worried it could make the code
harder to maintain and follow. Couldn't it? I am not sure anymore.
At the end I decided to start with a "loginService" which is kid of
specialized event bus for login related stuff. As I said, I am not
sure if the generic event bus would be a bad or good idea though. As
for the bringing an event bus into angular - it could be quite a
simple service considering current angular's infrastructure.
Introducing this could have a positive impact on how people try to
sort things out in their applications (considering a generic event bus
is fine).
Thanks,
Witold Szczerba
Going back to the $xhr and $xhr.error example, suppose one needs:
Acceptance criteria:
The $xhr.error, for every HTTP 500, to wait 10 seconds and retry. One
cannot ask for $xhr in $xhr.error and one cannot ask any other service
which depends on $xhr.
It looks like now - there is no simple solution for that task. The
only possible way, would be to introduce 2 extra services:
1) message bus - like middleman and
2) "http500RetryService"
Here we go:
============================================
service('$xhr.error', function(messageBus ) {
return function(request, response) {
if (request.status == 500) {
messageBus.publish("$xhr.error_http500", request);
}
}
}, {$inject:['messageBus']});
service('messageBus', function() {
....
....
....
....
....
... nice implementation of message bus ..
....
....
....
....
....
....
});
service('someEagerService', function($xhr, $defer, messageBus) {
messageBus.register("$xhr.error_http500", function(request) {
$defer(10 * 1000, function() {
$xhr(request.method, request.url, request.data, request.callback);
});
});
}, {$inject:['$xhr', '$defer', 'messageBus'], $eager: true});
============================================
That would work, but comparing it to a simple few lines of code:
============================================
service('$xhr.error', function($xhr, $defer ) {
return function(request, response) {
if (request.status == 500) {
$defer(10 * 1000, function() {
$xhr(request.method, request.url, request.data, request.callback);
});
}
}
});
============================================
makes me wonder if allowing interdependencies in angular would not be
something to consider.
What do you think?
Regards,
Witold Szczerba
--
You received this message because you are subscribed to the Google Groups "angular" group.
Years ago, most of the Java developers were saying the same things. Now they are in minority.
I was expecting the same will happen in JavaScript world, I mean, years will have to pass, but I am positively surprised.
Regards,
Witold Szczerba
--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.