I recently posted this question and figured out the direct solution (that being, I was able to cancel a promise/request when the route changed). However, I'm encountering another, related problem that I think belongs in a separate question so here it goes:
I'm able to abort my promise when the route changes just fine (as you can see from the question I linked). However, for some strange reason, any other requests on the other route are delayed when resolving. See my dev tools screenshot below.
Here's the scenario: I load route A, which makes the call to /api/categories and you can see it takes 30ms which is normal. Then I navigate to route B, then before it's done loading I return to route A. When I return, the call to /api/categorySites/1 is cancelled, and you can see when that happens as the gray bar ends. This is done by aborting the promise. However, back on route A again, the call to /api/categories doesn't resolve until that gray dot appears again on the request that was cancelled. That second call to /api/categories shouldn't take 2.23s, it should be closer to 30ms.
What's going on here? I would think the second Route A request would be just as fast as before. I need to get this to work faster. My code is in this question. Let me know if you think I should include it again here. It's hard for me to imagine this isn't a common problem too...
This is an older post but I did look into this and this sounds like eager vs. lazy asynch transition that I read about in Emberjs documentation recently. On your routes (and subsequent aborts) fulfills the promise (completes), moves along to your re-route request.
I believe this can be improved with a state controller.
There is an Angularjs ui-router state controller that might be of use.
Here are example examples.
Angularjs routing documentation (for posterity).
So this is about $routeProvider (Angularjs default) enhanced by $stateProvider (ui-router) to expedite aborted routes.
Hope this is helpful (roughly 312 days later).
Related
"$digest already in progress" when manually changing URL
I have a hybrid AngularJs/Angular app. If I'm on a page, say localhost/home, and I manually edit the URL to localhost/otherPage and hit enter, the browser navigates to the other page, but I get this error:
The error does not occur if:
I navigate to the same page using in-app links
I open a new tab to navigate directly to localhost/otherPage
The stacktrace doesn't show any of my code, so I'm not sure how to debug this. Also, I don't know what difference it makes to the router whether you're "editing" the URL to navigate from home to otherPage as opposed to directly resolving the otherPage URL in a new tab.
Thanks for any help!
From the Docs:
Diagnosing This Error
When you get this error it can be rather daunting to diagnose the cause of the issue. The best course of action is to investigate the stack trace from the error. You need to look for places where $apply or $digest have been called and find the context in which this occurred.
There should be two calls:
The first call is the good $apply/$digest and would normally be triggered by some event near the top of the call stack.
The second call is the bad $apply/$digest and this is the one to investigate.
Once you have identified this call you work your way up the stack to see what the problem is.
If the second call was made in your application code then you should look at why this code has been called from within an $apply/$digest. It may be a simple oversight or maybe it fits with the sync/async scenario described earlier.
If the second call was made inside an AngularJS directive then it is likely that it matches the second programmatic event trigger scenario described earlier. In this case you may need to look further up the tree to what triggered the event in the first place.
For more information, see
AngularJS Error Reference - $rootScope:inprog - Diagnosing This Error
I'm trying to use angulars $http, with both a cache and an interceptor.
The quick question:
Currently when angular gets the answer from the server, it first caches it, and then it passes it through the interceptor.
Is it possible to force angular to first pass it through the interceptor and only then cache it?
The long issue:
The server responds every call with a format similar to:
{permission: BOOL, data:[...]}
In the interceptor response I check the permission, and if correct I throw it away and pass only the data field to the application level. If it fails I reject and popup an error, etc... (Maybe I should do it in a transformResponse function, but I'll endup facing the same issue).
Then for some API calls I'm requesting a bunch of resources like that:
/resource/ALL
And it obviously caches this request and answer, but what I want to do next is fake caching every resource that I received.
So forthcoming calls to /resource/{some resource id} are already cached, cause I've already received it in the call where I requested ALL.
The problem I'm facing is, when I want to fake cache, on the application level, I lost the "{permission: BOOL" part, cause I've thrown it in the interceptor.
Some notes:
1- Of course I could also fake the permission part, and just hardcode it, but I feel it's not an option since if I later add / modify / remove metadata it's another place I've to look at.
2- An other way would be to don't throw the metadata on the interceptor / transformResponse, but again this is not an option since I don't want to select the 'data' field every time I call $http on the application level.
So I think the best option for me would be to cache after the interceptor, and not before.
Hope I made the issue clear, and any answer is welcome!
My application has two views, each of these has two routes. When a user change the route of one view, the other should not be changed. This is achieved using sticky states.
One of the routes uses a resolve to go grab something from the server. In my application this is dependent on a route parameter which is simulated in the plunker I put together by returning a random number.
The issue is that the resolve only fires once which means, regardless of the route parameter, it ends up loading the same content and redirecting to the same URL every time.
Worse yet, adding {reload: true} to the state causes this error: state.params.$$keys is not a function. I've started reading the source but figured I should post here in case anyone had seen this before.
I would prefer not to refactor the app to avoid parallel states, and so would appreciate any other suggestions.
You are running into issue #112
https://github.com/christopherthielen/ui-router-extras/issues/112
I built from source and updated your plunk and it seems to be working correclty now when transitioning back and forth between ViewB RouteA and Route B
http://plnkr.co/edit/zpEXaJqXtJPH1pVKPVxj?p=preview
Stupid stackoverflow requires me to add code to the answer since i linked to a forked plunk. there's no code to add
The biggest problem is that I even don't really know how to describe the problem I'm asking about. It's the first time in more then a decade of wed development.
I'm working on a Rails 4.1.1 app and using angularjs pretty extensively, though I don't know it well yet. And everything seemed to be working fine up to the moment when I tried to add some browser history manipulation to my app (e.g. changing the displayed url when listing though a paginated list so that that url can be copied and distributed). To do this I added a config to my app.
#app.config ($locationProvider) ->
$locationProvider.html5Mode(true)
And then in my angular controller added the $location binding like this
$scope.$watch 'pagination.cur', (newVal) ->
$scope.loadNews newVal
$location.path("/news").search({page:newVal})
(this is ment to change the url in the browser searchbox when the user goes from one page to another).
That workes well, the url does change appropriately, but all the sudden all the html links on the page got broken. I mean litteraly. I click any link on the page (even outside the controller div), the url in the serchbox changes appropriately, but the turbolinks toes not fire the Ajax request to get the new page content. If I then refresh the page, it loads the correct page.
I know it's really weird. What's weirder, that I don't get any JavaScript errors or anything unusual.
The only way I found to get the links working again - is to remove that initial config.
But when I do it, the $location falls back to hashtag syntax, wich is really not at all what I want.
My only assumption is that there could be some kind of a conflict between angular $location service and turbolinks when handling browser history, but even if that's right, I have no idea how to get around it. And I really need that kind of manipulation, 'cause I'm going to be using it alot in this and other apps.
I really don't know, what other information on this problem may be usefull, don't hasitate to ask for updates. I'll post whatever I can.
P.S. Btw, can this kind of manipulation be done by means of turbolinks? 'Cause it's exactly the same thing turbolinks does when changing the displayed url after page body reload, but I can't find any documentation on its public API for that.
UPDATE
Have no idea what's the source of the problem yet, but it seems to be not related to the turbolinks gem. Removing turbolinks requirements from the application.js file does not change anything.
Using $window.history.pushState instead of $location.path solves the functionality problem, but does not explain the initial bug.
From the /posts/edit-view I'm submitting a form to the action addCategory in my Post controller.
The action does all the work it has to do, and subsequently calls $this->redirect($this->referer());.
At first sight my app works fine, but I encountered some hickups when moving to a production server. Monitoring the calls in Firebug I see that the action acually returns a 302 Found but the 'Response' is Failed to load source for: http://localhost/xps/posts/addCategory.
This happens on both dev en production servers, only on the production server it makes the redirect flow fail. On both servers the controller actions are executed well: category is added.
Removing all the code in the action results in the same failure. Removing the redirect removes the failure, but that's not getting me anywhere.
A second (though maybe irrelevant) irregularity is that the submit method of the form is identified as PUT in Firebug although I explicitly set it to POST in Cake.
I recently switched from CakePHP 1.3.4 to 1.3.6, but reversing does not change the behavior
I use the RequestHandler, Session and Auth components and call parent::beforeFilter() in beforeFilter().
I also found the following thread http://cakephp.1045679.n5.nabble.com/puzzle-over-activity-td1260972.html It suggests to remove $this->Auth->authorize = 'controller'; but I don't have that stated anywhere anyway.
Does anyone have an idea where to look next?
Just a guess, but if you are using Security component, it might cause problems. Also, sometimes when using the ajax and sessions it can cause problems. Maybe if the page requires sessions, you could try it without sessions and see if it works.
Ok, I found it.
The Failed to load source is still there but is not the cause of failure.
In one of my Behaviors I had a space after ?> which messed up the headers, which made me look into the wrong detail.