2

When clicking on a link, I can pass data to another page:

<div ng-repeat="app in apps | filter:{Name: searchText}" class="slide">
    <a href="#/app/{{app.Name}}">{{app.Name}} {{app.Version}}</a>
</div>

When the new page comes up, I see the app's name:

enter image description here

This is the markup to display the name:

<p>{{appName}}</p>

However, if I want to pass the ID, like this:

<div ng-repeat="app in apps | filter:{Name: searchText}" class="slide">
    <a href="#/app/{{app.Id}}">{{app.Name}} {{app.Version}}</a>
</div>

That doesn't work. When I click on the ID, nothing happens in the browser. There is no error in the F12 tools console window. And Fiddler shows no activity. I think it's because the ID has a slash in it (this is a RavenDB convention). This is what I see when I hover over the link:

enter image description here

Notice the last slash. I think that's messing things up.

So I tried a stackoverflow solution to escape the slash. Now when I hover, I see this:

enter image description here

I thought that would have done it, but I'm back to the same behavior: nothing happens when I click on it. Nothing in Fiddler either. What am I missing? (If I change the markup to pass the Name property again, things work. So the wiring is good.)

Edit

I just realized that it's not that nothing is happening. My route provider is kicking in and taking me back to the same page that I'm already on:

$routeProvider.otherwise({ redirectTo: '/apps' });

And this is the entire routing config:

app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/apps', { templateUrl: 'partials/apps.html', controller: 'appsController' });
    $routeProvider.when('/servers', { templateUrl: 'partials/servers.html', controller: 'serversController' });
    $routeProvider.when('/app/:appId?', { templateUrl: 'partials/app.html', controller: 'appController' });
    $routeProvider.otherwise({ redirectTo: '/apps' });
}]);

Workaround

Setting a route like this allows me to hit the right page. The only issue is that I need to prefix the number part of the ID (on the receiving page) with the literal "applications/". I guess I can do that.

$routeProvider.when('/app/applications/:appId?', { templateUrl: 'partials/app.html', controller: 'appController' });

For completeness, this is what I had to do in the receiving controller:

.controller('appController', function ($scope, $routeParams) {

      $scope.appId = "applications/" + $routeParams.appId;
})
2
  • Maybe you just need to define another route that matches the URL w/the app ID... It's hard to say unless you show us the "$routeProvider.when()" statements that you call/declare in your app ;) Commented Aug 19, 2014 at 2:18
  • I just added that to my post. I also used your workaround. If no one has an actual way to pass the entire string with the slash in it, I'd be happy to accept your answer. Thanks! Commented Aug 19, 2014 at 12:23

1 Answer 1

3

This fiddle reproduces you problem. It is a small application which has 2 routes: /apps and /app/:appId. If the /app/:appId route is taken, the page displays Hello, {{appId}}, otherwise it displays Hello, apps. In the startup method (run), I've added a hard-coded redirect to '/app/applications%2F1121' using $location.path. As you can see, changing the route using $location.path('/app/applications%2F1121') works well: the application starts and gives us the right ID: Hello, applications/1121. However, changing the route using a href doesn't work: if you click the link, the app displays Hello, apps, meaning the /apps route was taken after the /app/applications%2F1122 url found in the link was not recognized.

Therefore, another workaround is to always use $location.path to change routes. Put this function in your $routeScope and use ng-click to call it (fiddle).

.run(function ($rootScope, $location) {
    $rootScope.go = $location.path.bind($location);
})

<a ng-click="go('/app/applications%2F1122')" href="">

Escaping the slash is still required, but this workaround does not require you to change your route configuration, so it can handle any ID.

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

7 Comments

I'm trying to understand how this is wired together. Why would the run function have a hard-coded path? And when I clicked on the App 1122 link, I see this: Hello, apps. I was hoping I'd see Hello, applications/1122. No?
There are two fiddles in my answer. The first one has your issue so when you click on the link, the $routeProvider doesn't recognize the route and redirects you to /apps and you Hello, apps. The second one works fine so when you click the link, you will see Hello, applications/1122.
The hard-coded path in run is there just to test if changing the route with $location.path works or not. The fact that the page displays Hello, applications/1121 proves that it works.
I've updated my answer to explain a little bit more how the fiddle's app works.
I think I'm close. The problem is that I see {{app.Id | escape}} on the receiving page. I'm assuming that's because it's treated as a literal due to this HTML: ng-click="go('/app/{{app.Id | escape}}')". In your example, you're using the literal ID, but I have to use a variable. Do you know how I get past this part?
|

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.