Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active October 30, 2019 01:42
Show Gist options
  • Save ryanflorence/6833014 to your computer and use it in GitHub Desktop.
Save ryanflorence/6833014 to your computer and use it in GitHub Desktop.
Comparing an avatar implementation with angular and ember. http://www.angularails.com/articles/creating_simple_directive_in_angular
// Because people can't seem to find the gist description, here is the source
// of this code, a post found in last weeks JS Weekly, it is not my code
// http://www.angularails.com/articles/creating_simple_directive_in_angular
angular.module('ui-multi-gravatar', [])
.directive('multiAvatar', ['md5', function (md5) {
return {
restrict: 'E',
link:function(scope, element, attrs) {
var facebookId = attrs.facebookId;
var githubUsername = attrs.githubUsername;
var email = attrs.email;
var tag = '';
if ((facebookId !== null) && (facebookId !== undefined) && (facebookId !== '')) {
tag = '<img src="http://graph.facebook.com/' + facebookId + '/picture?width=200&height=200" class="img-responsive"/>'
} else if ((githubUsername !== null) && (githubUsername !== undefined) && (githubUsername !== '')){
tag = '<img src="https://identicons.github.com/' + githubUsername + '.png" style="width:200px; height:200px" class="img-responsive"/>';
} else {
var hash = ""
if ((email !== null) && (email !== undefined) && (email !== '')){
var hash = md5.createHash(email.toLowerCase());
}
var src = 'https://secure.gravatar.com/avatar/' + hash + '?s=200&d=mm'
tag = '<img src=' + src + ' class="img-responsive"/>'
}
element.append(tag);
}
};
}]);
App.XAvatarComponent = Ember.Component.extend({
tagName: 'img',
classNames: 'img-responsive',
width: 200,
height: 200,
service: 'gravatar',
src: function() {
return this[this.get('service')+'Url']();
}.property('service', 'user'),
facebookUrl: function() {
return 'http://graph.facebook.com/' + this.get('user') + '/picture?type=large';
},
githubUrl: function() {
return 'https://identicons.github.com/' + this.get('user') + '.png'
},
gravatarUrl: function() {
var hash = md5.createHash(this.get('user').toLowerCase());
return 'https://secure.gravatar.com/avatar/' + hash + '?s=200&d=mm';
}
});
Angular
<multi-avatar data-facebook-id="717976707"/>
<multi-avatar data-github-username="jwo"/>
<multi-avatar data-email="jesse@rubyoffrails.com"/>
Ember
{{x-avatar service="github" user="rpflorence" width=50 height=50}}
{{x-avatar service="facebook" user="717976707"}}
{{x-avatar user="ryanflorence@example.com"}}
@ryanflorence
Copy link
Author

@bclinkinbeard I have a pretty deep understanding of angular and have built a few (admittedly trivial) apps with it. And, again, I didn't write that angular code, it was taken wholesale from a popular blog post featured in JS Weekly.

@mgol
Copy link

mgol commented Oct 8, 2013

@RyanHirsch @rpflorence It's not just Angular, '' is interpreted as '' by HTML5 browsers; the slash is stripped. That's why the above example is incorrect.

@bclinkinbeard
Copy link

Thinking about this more (unfortunately), the problem with the original Angular code isn't really a lack of idiomatic-ness. Sure, accessing the attrs directly instead of properly defining a child scope is less than ideal, but the biggest problem is the multi level conditional spaghetti. Breaking that out into a set of clean *Url functions isn't an Angular or Ember best practice/idiom, it's just fundamental code organization.

If you took the original Ember code and removed the separate service parameter and stuffed the *Url functions into src and navigated them with nothing but conditionals it would be shitty code too. I realize the Angular code was apparently linked from a popular newsletter, but it's still fundamentally bad code IMO. Not bad Angular code, just plain old, regular bad code.

@malsup
Copy link

malsup commented Oct 9, 2013

JS Weekly. LOL.

@ryanflorence
Copy link
Author

@bclinkinbeard for background, a friend said "how would you do that in ember" so I did it, made the gist and then the fun began. Here's my original tweet: https://twitter.com/ryanflorence/status/386241210337067009 I did not intend to say this is a valid or fair comparison, I was just answering a question for a friend. People take these things way too seriously. Both frameworks are great and arrive at nearly identical usage syntax <component attr=value>, {{#component attr=value}}.

I think there is value in considering the APIs the two frameworks give you for people picking one.

Most angular APIs just give you a single function hook to fill in and possibly return from (controllers, link, module, service), so people tend to drop everything into it because angular doesn't prescribe how to structure the code inside the hook. Makes getting started super easy.

Ember requires you to extend its objects (controller, component, route), which means you provide an object literal to your new constructor definition, rather than fill in a function body and return from it, so people tend to write methods because they didn't have to decide how to structure their modules.

I won't claim one is better, I just know which one I prefer.

@coderstash
Copy link

Nice gist! I know which one I choose/use :)

@polotek
Copy link

polotek commented Oct 11, 2013

@rpflorence I'm pretty sure I'm the one that screwed you here. I tweeted this as a "comparison" of ember and angular. https://mobile.twitter.com/polotek/status/387601840516259841

I didn't read the gist description and screwed up the context for everybody. Sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment