-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Resource.get xhr is not executed when updating to Angular 1.1.4 #2438
Comments
Interestingly the get call is executed if wrapped into a $scope.$apply call:
See this discussion for details: https://groups.google.com/forum/?fromgroups=#!topic/angular/MkXDfkPDI_g |
same problem. your solution works as well. |
I've seen this, too. The following fails (the callback is never invoked). Customers.query({
terms : terms
}, function (results) {
$log.log('Callback.', results)
}) But the following works fine. $scope.$apply(function () {
Customers.query({
terms : query.term
}, function (results) {
$log.log('Callback.', results)
})
})
Now, this is getting called from outside the Angular digest cycle, but it has worked prior to 1.1.4. |
Seeing this as well, any update on if this is intended behavior? Also, any hunches on what change caused this? (presumably changes to the promise that is associated with |
@aflock (and others), on second thought, this probably is intended behavior. In my use case, the block I shared I called from a jQuery plugin. Any other AngularJS call that participates in the digest lifecycle would have the same requirement (to be wrapped in |
I don't think this is intended behavior. Take a look at this fiddle http://jsfiddle.net/s3THR/7/ . To your point @michaelahlers why should resource be bound into a digest lifecycle? Shouldn't it be able to function independently? That's a facet of this I am unsure of, but my gut says it should be able by itself. |
@aflock, I seem to remember that an upcoming enhancement for |
I definitely think this is a bug in $http, possibly introduced in 4ae4681.
|
git bisect confirms, issue introduced in 4ae4681 |
It seems this was a known change introduced by this PR #2130, but not listed in the change log. Not sure if the consequences were totally known. |
@michaelahlers, I doubt this was intended behavior since the natural expectation is that $http and $resource run in the Angular execution context - and thus an additional $apply should actually cause an error. If for some reason this was intended, then as we can see from the numerous bug reports re this issue, there is widespread confusion. Personally - I reverted to 1.0.6 rather than modifying my code, with the expectation that future versions will be fixed back to "expected" and documented behavior. It would be nice to get guidance from the core team on this. |
So we still see the differences in behavior between 1.1.5 and 1.0.7 - I tried @c0bra's Plunkers above with the new releases. So my guess is that this is the new $http/$resource behavior. Can we _please_ get clarity and guidance on this from the core team? What are the new best practices for $http and $resource? I doubt the solution is to wrap $http calls with $apply - feels like a complete hack. |
It's passing testing because in resourceSpec.js we have this:
Where |
@mokesmokes I'm not sure it will negatively impact performance, I believe the digest is simply no longer done by $http, now that it is wrapped in a promise to allow chaining. It is a breaking change though, and I like @c0bra's suggestion in here: #2431. Unfortunately I'm not sure if we'll get any word from the angular team without a pull request :( |
I'm restating my position at this point, but this behavior is logical for the reasons @aflock gives. Any time you invoke Angular operations from external libraries, you've got to do this. It is a bug, however, if you need to wrap |
The fact is that you didn't have to do this in testing up until now, or in activities that were not part of a $digest cycle, e.g. in an event handler. |
@aflock, following the code path in 1.0.6, there was no prior digest cycle, and intuitively none was needed. In 1.0.6 the $http flow basically checks the cache, and if the request is not cached it does the expected - issues an xhr in completely standard fashion. Digest cycles should only be required at the completion to update the bindings. The new flow is not only breaking, in my opinion it's counterintuitive with the entire API. I'm not saying it's necessarily bad - I am saying the logic is far from intuitive (and I admittedly don't get it), and an in depth explanation, code samples, etc are urgently needed. I would love to upgrade to 1.1.5, but holding off until I thoroughly understand how we're supposed to use $http and $resource. |
@mokesmokes completely agree. perhaps @mhevery , @vojtajina or @IgorMinar could shed some light? |
@michaelahlers - I respectfully disagree with your last post - e.g. $timeout. For $timeout, $apply() is called unless you explicitly set invokeApply to false. This is the case in 1.0.6 and 1.1.5. You normally need to wrap code in $apply only when you update the model outside the Angular context. Angular functions are expected, by default, to run in Angular context, as $http and $resource prior to this change, and $timeout et. al in all versions. |
Is there any update on this issue? Is the correct way to resolve this to wrap the call in $scope.$apply() when outside of a regular angular context (e.g. calling from jQuery)? This gave me a terrible time trying to figure out what was going wrong between moving from 1.0.6 to 1.1.4, it'd be nice to have this behavior documented. |
Yes that's correct, see discussion here: #2431 |
@aflock Thanks much. Is there a reason why this issue is still open? It made it seem like the proper resolution for this was not found yet. |
@StephenCWan You are right, it should get closed now. |
This change causes a new $digest to be scheduled in the next tick if a task was was sent to the $evalAsync queue from outside of a $digest or an $apply. While this mode of operation is not common for most of the user code, this change means that $q promises that utilze $evalAsync queue to guarantee asynchronicity of promise apis will now also resolve outside of a $digest, which turned out to be a big pain point for some developers. The implementation ensures that we don't do more work than needed and that we coalese as much work as possible into a single $digest. The use of $browser instead of setTimeout ensures that we can mock out and control the scheduling of "auto-flush", which should in theory allow all of the existing code and tests to work without negative side-effects. Closes angular#3539 Closes angular#2438
This change causes a new $digest to be scheduled in the next tick if a task was was sent to the $evalAsync queue from outside of a $digest or an $apply. While this mode of operation is not common for most of the user code, this change means that $q promises that utilze $evalAsync queue to guarantee asynchronicity of promise apis will now also resolve outside of a $digest, which turned out to be a big pain point for some developers. The implementation ensures that we don't do more work than needed and that we coalese as much work as possible into a single $digest. The use of $browser instead of setTimeout ensures that we can mock out and control the scheduling of "auto-flush", which should in theory allow all of the existing code and tests to work without negative side-effects. Closes angular#3539 Closes angular#2438
This change causes a new $digest to be scheduled in the next tick if a task was was sent to the $evalAsync queue from outside of a $digest or an $apply. While this mode of operation is not common for most of the user code, this change means that $q promises that utilze $evalAsync queue to guarantee asynchronicity of promise apis will now also resolve outside of a $digest, which turned out to be a big pain point for some developers. The implementation ensures that we don't do more work than needed and that we coalese as much work as possible into a single $digest. The use of $browser instead of setTimeout ensures that we can mock out and control the scheduling of "auto-flush", which should in theory allow all of the existing code and tests to work without negative side-effects. Closes angular#3539 Closes angular#2438
This change causes a new $digest to be scheduled in the next tick if a task was was sent to the $evalAsync queue from outside of a $digest or an $apply. While this mode of operation is not common for most of the user code, this change means that $q promises that utilze $evalAsync queue to guarantee asynchronicity of promise apis will now also resolve outside of a $digest, which turned out to be a big pain point for some developers. The implementation ensures that we don't do more work than needed and that we coalese as much work as possible into a single $digest. The use of $browser instead of setTimeout ensures that we can mock out and control the scheduling of "auto-flush", which should in theory allow all of the existing code and tests to work without negative side-effects. Closes angular#3539 Closes angular#2438
The code below works fine in 1.1.3, but does nothing in 1.1.4. It only prints "after get" and it seems as the get branch is never entered. From the debugging console I can see that no xhr request is issued.
The text was updated successfully, but these errors were encountered: