2

I want to be able to use part of the URL in a controller, in this case to be able to set a body class based on the URL, but I would also like to use a service to fetch other information from a json file based on that URL.

If I use console.log to check what's in $scope.pageDetail.id withing the for loop, I get the correct response, but it returns "undefined" outside of the for loop. Everything works on page reload, but not when I use the page's navigation to click my way through the urls.

My controller:

oddproto.controller('UrlController', function($scope, $location, PageService){

  // Get page id from URL
  var pageId  = $location.path().replace("/", "");

  $scope.pageDetail = PageService.query(function(data) {
    // Get the correct page details from the dataset
    for (var i = 0; i < data.length; i++) {
      if (data[i].id === pageId) {
        $scope.pageDetail = data[i];
        break;
      }
    }
  });

})

My service

oddproto.factory('PageService', function($resource) {
  return $resource('includes/pages.json');
});

pages.json

[
  {
    "id": "blog",
    "name": "Blogg"
  },
  {
    "id": "cases",
    "name": "Projekt"
  },
  {
    "id": "contact",
    "name": "Kontakt"
  }
]

I've also tried doing this entirely without the service, i.e.

$scope.pageDetail = $location.path().replace("/", "");

But that only works on page load as well, so it seems to me like $location is the issue here. I don't know what else I can use though.

2 Answers 2

4

Your controller is not recognizing the location change. When the controller is initialized, it sets the page id, but after changing, your controller is not re-initialized. For this, you should use

scope.location=$location;
scope.$watch('location.path()', function(path) {
  $scope.pageDetail = ....
});

This will observe location.path() and if its changing, it does your custom magic.

Furthermore, I suggest you to make your controller to be a directive, as it is only dealing with styling your body-tag.

Sign up to request clarification or add additional context in comments.

3 Comments

I can't get it working using $watch as your example states, probably because I'm not sure how to use it (I'm having a hard time grasping it even after reading the docs). I tried something simple and left out the service and used: $scope.$watch('location.path()', function(path) { $scope.pageDetail = $location.path().replace("/", ""); }); But that didn't update the controller either. $scope.pageDetail still only returns the inital page load path.
well, I don't know, what might be the problem in your specific case, but I use something like this, I coded some tome ago and it works :S stackoverflow.com/questions/12592472/…
Ahh, after reading my own post, I realized, you have to add the location to the scope, to be observed via scope scope.location=$location; Updated my answer
1

I got it working using $routeChangeSuccess

  $scope.$on('$routeChangeSuccess', function() {
    $scope.pageId = $location.path().replace("/", "");
  })

There might be an issue in angular using $watch for in regards to $location

2 Comments

My bad, if you want to watch something on the scope, you have to add it to the scope before
Ok, I have a working solution now, but I did learn a lot about $watch thanks to you. I'll see if I make a new go at using $watch again instead of $routeChangeSucess. $watch is a lot more powerful

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.