4

My view is automatically redirecting to default (otherwise) view and I have no idea why. When I click, it goes from View1 to View2 and then automatically redirects to default View3. I checked by putting console.log() in View2

View1 -> View2 -> View3

myApp.config(function ($stateProvider, $urlRouterProvider) {
    $stateProvider
        .state('view1', {
            url: "/view1",
            templateUrl: "App/Views/start/view1.html",
            controller: 'MyController'
        })
        .state('view2', {
            url: "/view2/:details",
            templateUrl: "App/Views/start/view2.html",
            controller: 'MyController'
        });
     $urlRouterProvider.otherwise('/view3');
    });

And I am calling $state.go like this.

$state.go('view2', { details: JSON.stringify(response.details) });

I tried to intercept it by preventing default on $stateChangeStart but ran into an error :

$digest() iterations reached. aborting

which is due to an interaction issue between $urlRouterProvider and $stateProvider as explained here. But even if I intercept it successfully, I am not sure if that's the correct way. So what is actually causing it? Or How can I find out what's causing the redirect. By the way I have already checked for $stateChangeError and there are none.

myApp.controller('MyController', ['$scope', '$stateParams', '$state', function ($scope, $stateParams, $state) {
 $scope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
    if (toState.name == "view3" && fromState.name == "view2") {
        event.preventDefault();
    }
 });
});
Community
  • 1
  • 1
Lokesh Suthar
  • 3,201
  • 1
  • 16
  • 28
  • Would be useful if you posted the contents of 'tab.congratulations' which is apparently the cause of the problem. – ProLoser Dec 05 '14 at 21:25
  • I think the cause of the problem is HTML, can you please share the html code – harishr Dec 06 '14 at 05:49
  • I am pretty sure, there it's not the HTML as I tested an empty template too and it behaved the same way. I seriously doubt if it has something to do with the route parameter. Also sorry for the discrepancies, I changed all the view names, here to generic and forgot to change one. I have edit out the those discrepancies. – Lokesh Suthar Dec 06 '14 at 21:38
  • If you could post a plunker then we could probably find the error faster, I don't think there is enough information here. – Callum Linington Dec 06 '14 at 23:15
  • Well, the thing is I am using Ionic framework to develop a hybrid mobile app and I am not sure, If I'd be able to reproduce the same error on Plunkr. I'd really appreciate it, if you could just guide me through how to debug this. – Lokesh Suthar Dec 08 '14 at 05:21
  • Sorry for the misleading, I thought that was a copy-paste. – Preview Dec 08 '14 at 09:14
  • I am quite sure that `$stateParams` are causing it. I will try to recreate this on plunkr. – Lokesh Suthar Dec 08 '14 at 12:27
  • what is response.details? – Scottux Dec 08 '14 at 21:34
  • I am receiving the JSON data via AJAX call. – Lokesh Suthar Dec 09 '14 at 05:18

3 Answers3

4

I think your response.details has non-url encoded characters making the route provider think that you are navigating to a deeper page i.e. var response = {details:'bar/foo'}; would in effect be navigating to /view2/bar/foo triggering your otherwise.

Scottux
  • 1,577
  • 1
  • 11
  • 22
  • Well, that makes sense but I am stringifying the response, wouldn't that help? Also it is going from view1 -> view2 --Automatic redirection-> view3. It is not skipping view2 but I will try to escape the string again. – Lokesh Suthar Dec 09 '14 at 05:16
  • I think you are right. I just tested encoded the string and it worked in one case. Let me Test out some more cases and I will mark your answer as correct. – Lokesh Suthar Dec 09 '14 at 06:23
  • $state.go builds the url to hand off to Angular's routing. So anything with a '/' or '?' or '&' could trash it. Not sure about the JSON characters. Ideally state params are simple strings or numbers. What are you doing to want to pass data in this manner? – Scottux Dec 09 '14 at 18:00
  • Let's say I am saving an object and After successful call, API returns an object, and I am showing that object on a different view. Now either I could use `$rootScope` to pass that object to the view or I can pass it as a `$stateParam` I opted for the latter because I would be using this view at various places. – Lokesh Suthar Dec 10 '14 at 12:23
  • You should probably look into using a Service. You can stash the response in a service and then ask for it back in the next controller. Let's say you have an ItemList controller and an ItemEdit controller, you can have an Item service that stores the list for you in case you delete an item then the delete returns the new list, the service is injectable and a singleton so it will share state. – Scottux Dec 10 '14 at 13:59
  • I am using services. I currently use `localStorage` for storing the data. What else would you recommend? – Lokesh Suthar Dec 10 '14 at 19:02
  • if using localStorage, just pass the key as the state parameter then you can look it up from there rather than using rootScope or passing a glob of data to the router. Or have the service store a reference to the current item and update that reference on save. Then any controller can access it statefully without rootScope. – Scottux Dec 11 '14 at 17:17
1

This is kind of a shot in the dark, but try putting your $urlRouterProvider before the $stateProvider. I think that what could be happening is that the $urlRouterProvider.otherwise() is acting as a catch all with a watcher, but by the time it is in scope all of the routes have already been run through. This means that even if the $stateProvider works and sends a request to the correct URL, the $urlRouterProvider.otherwise() will catch the request as if that didn't happen and will send it to the default page.

RadleyMith
  • 1,313
  • 11
  • 22
1

If I understand your question, you want to know where to debug first. I recommend adding a console.log for your response.details, since you aren't providing that in your question.

I do not believe this is an order of operations issue in your definition because you say this is happening on click, when you call $state.go(). At the moment that you do that, the router will attempt to find and quality the state you've requested. Since your state has a URL, it will also try to send the user to that URL, using the parameters you've provided.

Since your failure is happening at that point, the most logical explanation is that your target route is not reachable, or the router thinks it isn't. Since your route includes a parameter, this most likely means the router is not accepting your parameter - this path is set up to have that parameter be required, so if it is not there (or isn't passing validation), you'll trigger .otherwise().

You can rule this out very easily by simply removing the parameter from state2's URL. Of course you want it, but if removing it allows you to reach the state then it is the parameter. If removing it still doesn't allow you to get there, it's something else and you will need to set a breakpoint inside the $state.go() call and trace out where it's rejecting you. Make sure you use the un-minified files while doing this.

Chad Robinson
  • 4,575
  • 22
  • 27
  • Hi Chad, Just wanted to clarify that it is not failing but redirecting automatically and immediately from second to 3rd view. I have successfully checked this by various stateChange events provided by angular. Also I put called a console.log on view2 and it was logged, so it is being called – Lokesh Suthar Dec 09 '14 at 05:14
  • Same story as @LokeshSuthar above. Stringifying your data does not necessarily make it URL-safe. Not-skipping-the-route doesn't tell you much - $stateChangeStart is fired at the START of a state change. It doesn't mean there wasn't an issue. You should still try view2 without any parameters required in the URL. Also, make sure you register a handler for $stateChangeError, which will fire with details about state change problems. – Chad Robinson Dec 09 '14 at 06:02
  • Chad I did register that handler but it showed nothing, that's why I called it a successful redirection. – Lokesh Suthar Dec 09 '14 at 06:06