If There is No Profile Image, Show a Placeholder Glyph-Icon using Angular
The Problem:
We want to snag a photo out of a folder that holds profile pics. However, we don't have profile pics for everyone. When there isn't a profile photo, we want to show a placeholder image, which is a glyph-icon.
The Solution:
We wrote some JS that sends a path for a profile pic to the dom. If the dom doesn't get a path, it shows a glyph icon.
Our approach...
What the HTML below says is, "Run the profileImage function. If it's truthy, set the background image to the path the function spits out. If it's falsy, don't show anything - the glyph will show instead."
The HTML:
<div class="associate-photo" ng-style="{{journalEntry.profileImage()}}">
<i ng-hide="{{journalEntry.profileImage()}}" class="glyph-circle-user journal-user-glyph {{ journalEntry.getAcceleration() }}"></i>
</div>
The JS:
$scope.journalEntry.profileImage = function(){
if ($scope.journalEntry.user && $scope.journalEntry.user.Namecode) {
return {
backgroundImage: "url('" + profilePicBaseUrlFactory + $scope.journalEntry.user.Namecode + ".jpg" + "')"
};
}
};
Line by line, here is what the JS code says...
$scope.journalEntry.profileImage = function(){
// When you see journalEntry.profileImage, then...
if ($scope.journalEntry.user && $scope.journalEntry.user.Namecode) {
//Check out the individual entry that is on the scope. If it has a user name and a namecode then...
return {
backgroundImage: "url('" + profilePicBaseUrlFactory + $scope.journalEntry.user.Namecode + ".jpg" + "')"
// Return the path that we get when we run the profilePicBaseUrl function and we add the namecode plus jpg to the end of it...
// thus creating a string that is a path name
};
}
};
If it is TRUTHY, what we end up seeing when we run this code in the browser is...
<div class="associate-photo" ng-style="{"backgroundImage":"url('assets/images/associates/kali.jpg')"}" style="background-image: url(http://localhost/~kkiger/project/build/assets/images/associates/kali.jpg);">
<i ng-hide="background-image: url(http://localhost/~kkiger/project/build/assets/images/associates/kali.jpg);" class="glyph-circle-user journal-user-glyph acceleration-neutral ng-hide"></i>
</div>
Effectively, if there is an image, <i>we see a path to the image assigned to the backgroundImage rule</i>. Normally these rules are found in CSS files, but they can be right there in the HTML too! Example of what a standard background image set to a URL in CSS looks like below... See, you can match that up to the URL in our code, right?
background-image: url(http://www.example.com/bck.png);
If it's FALSY, ng-hide gets and empty string (see below) and we see the glyph...
<i ng-hide="" class="glyph-circle-user journal-user-glyph acceleration-positive"></i>
So, we see the placeholder glyph in the spot where the profile pic would normally be.
How the magic happens...
It all comes down to these 2 Angular directives - Ng-style hides or shows the profile pic and ng-hide shows the glyph when it is needed.
Here's the Angular documentation for ng-style: "The ngStyle directive allows you to set CSS style on an HTML element conditionally." Ie., ng-style lets you apply CSS sometimes, when you want it, vs all the time.
A little more detail... "[Ng-style is an] expression which evals to an object whose keys are CSS style names and values are corresponding values for those CSS keys. Since some CSS style names are not valid keys for an object, they must be quoted. See the 'background-color' style in the example below."
Umm, what? Ok, in English... With ng-style, you can insert things into the dom. The things you insert are CSS styles. Not only can you insert the style name, but you can insert the values for that style rather than having to have those in a CSS file. So, why not just use ng-show? The cool thing about ng-style is that it doesn't cause an error if the jpg isn't found, whereas ng-show does.
Here is the Angular documentation for ng-hide: "When falsy, the .ng-hide CSS class is removed from the element causing the element NOT to appear hidden."
<i>OMG how do I know which Angular thing I need?!?!</i> Ng-show and Ng-hide are tricky. If you know a function is going to return something truthy, and you want to show that thing when it is truthy, you use ng-show. Meanwhile, if you have a function you know is going to return something falsy, and you want to show that thing when it's falsy, then you use ng-hide. Ng-show is like "show on truthy/unshow on falsy". Ng-hide is basically like "unhide on falsy/hide on truthy". Crazy word games, huh?
Now that you know how to use a function to set a background image with Angular, check out how you can use Angular to set the color on a glyph in "Set the Color on a Div, Span, or Glyph-icon in Response to Data."