3

Can someone point me how to do a conditional href rather than duplication an a tag to do a hide/show.

Here's what I'm trying to do here, if DisplayLocation is null then use a string of "unknown" otherwise use the location. I tried something like x ? y : "unknown" but I dont think that works in href.

<a class="btn-main orange" href="#!/movie-details/
   {{movie.Item.DisplayLocation | prettify}}/
   {{movie.Item.Title | prettify}}/{{movie.Item.Id}}" 
   id="view--{{$index}}"> View
</a>

Fix:

<a class="btn-main orange" data-ng-href="#!/movie-details/
   {{movie.Item.DisplayLocation ? 
       movie.Item.DisplayLocation : 'unknown' | prettify}}/
   {{movie.Item.JobTitle | prettify}}/
   {{movie.Item.Id}}" 
   id="view--{{$index}}">View
</a>
3
  • use ng-href Commented Nov 30, 2015 at 17:41
  • but how can I actually do the conditional part though? Commented Nov 30, 2015 at 17:43
  • If it's inside the double curlies, angular should treat it as an expression and properly evaluate the conditional. Commented Nov 30, 2015 at 17:44

2 Answers 2

4

You could instead create a function in your controller, which then is used in your bindings.

Controller:

$scope.returnConditionalDisplayLocation = function returnConditionalDisplayLocationFn() {
    return $scope.movie.Item.DisplayLocation ? 
           $scope.movie.Item.DisplayLocation : "unknown";
}

HTML:

<a class="btn-main orange" 
   href="#!/movie-details/{{returnConditionalDisplayLocation() | prettify}}/
   {{movie.Item.Title | prettify}}/{{movie.Item.Id}}" id="view--{{$index}}"> View
</a>

This way you separate logic into the controller where it belongs, cleaning up your HTML at the same time!

EDIT:

It is OKAY to use href however if a user clicks on the link before angular has time to render the binding values for the href then they will reach a bad url.

Therefore you want to use ng-href per Angulars Documentation

In the same way as above you would write:

<a class="btn-main orange" ng-href="#!/movie-details/
   {{returnConditionalDisplayLocation() | prettify}}/
   {{movie.Item.Title | prettify}}/{{movie.Item.Id}}" 
   id="view--{{$index}}"> View
</a>
Sign up to request clarification or add additional context in comments.

4 Comments

You'll still need ng-href. Otherwise the href will be interpreted literally and not evaluated as an expression.
Nope. href is one of the few attributes that angular can't modify without bad consequences. That's why they provide ng-href and ng-src.
I'm sorry, @ryanyuyu before you go and downvote without checking your answer, codepen.io/TheLarkInn/pen/epqKod the only 'bad consequences' you are talking about is that someone clicks the link before the bindings update the anchor href. Regardless of your downvote, I updated the answer to reflect both alternatives.
@SeanLarkin You should never assume the downvote was mine (voting is anonymous). Your answer is better now though.
1

Move everything into one expression, and let the filters be processed as sub-expressions. Then you can get what you want with a very small footprint and no cluttering of your controllers:

<a class="btn-main orange" href="#!/movie-details/{{ !movie.Item.DisplayLocation ? 'unknown' : ((movie.Item.DisplayLocation | prettify) + '/' + (movie.Item.Title | prettify) + '/' + (movie.Item.Id)) }}" id="view--{{$index}}">View</a>

The extra parentheses are optional but add clarity in my opinion. Also as ryanyuyu pointed out, use ng-href to prevent a flash of un-parsed content.

3 Comments

@Sean Larkin your answer is valid also but I believe that the "Angular way" says to keep your controllers as lean as possible. This means if it can be easily solved with an expression (like I did here) then it's not worth cluttering the controller and adding an extra method solely for the purpose of conditional logic that expressions can nicely handle. Imagine if he had this problem in more than one area - your approach would add multiple controller methods and bloat the code.
An expression in HTML makes my eyes hurt, one of my pet-peeves against angular, I prefer logic in actual code, not as strings in HTML attributes
Angular wants you to keep your controllers lean, ie: place them in whatever backend is managing the data, not dump said logic into your view. If the problem is elsewhere, as you mentioned, you'd still be repeating code just like you would be with your controllers.

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.