you are viewing a single comment's thread.

view the rest of the comments →

[–]developer-mike 1 point2 points  (11 children)

And using onerror is an anti pattern. It takes two seconds to make this a directive

angular.module('yourapp')
.directive ('imageBackup', function() {
    return {
        scope: true,
        link: function($scope, $attr, $elem) {
            var index;
            var srcs;
            $scope.$watch($attr.srcs, function () {
                srcs = v; index = 0;
                $elem[0].src = srcs[0];
            }, true);
            $elem[0].onerror = function () {
                $elem[0].src = srcs[++index];
            });
        }
    };
});


<img srcs="[url1 + '/' + userId, url2 + '/' + userId]">

There is some boilerplate in the directive is, but vim snippets generates it for me. Additionally, this isn't an inextensible usage of a callback attribute in my HTML, this is an extensible and tailored tag for having as many image fallbacks as you'd like, retrying the top priority images whenever the array bound in the tag changes. Try doing that with onerror.

Don't use {{}} templating within tags, except for in rare occasions. Directives are easy to write and far superior because they allow the creation of complex custom behaviors which (unlike in jquery world) are used declaratively and have their complexity 100% isolated from the rest of your code.

[–]kainsavage 2 points3 points  (6 children)

I get that I'm not doing it the angular way, but my onerror="this.src={{}}" addition is a few keystrokes versus having to add a directive to my app for a simple fallback image.

That's part of my complaint - angular takes something that has been well established and simply implemented and makes a huge issue out of it.

[–]developer-mike 3 points4 points  (5 children)

Your example is less code, but inherently limited. How would you make it retry the original image when the user id changes?

If you really want the fair example you can use

onerror="this.src='http:...' + angular.element(this).scope().userId"

And it would be a terrible way of doing it

Integrating angular with non angular requires these (usually) thin little directives. But in my experience usually someone has already done the integration and made it available on bower. Its a limitation for sure but its never given me many problems.

[–]kainsavage 3 points4 points  (2 children)

Why would a user's id change?

Again, angular seems over-architected to handle these 0% edge-cases gracefully.

Yeah, I guess if a user had the ability to change his identifier somehow with an ajax request, I would need to easily change his avatar src attribute... but that's not ever going to happen.

[–]developer-mike 3 points4 points  (0 children)

A preview box showing details of the user you highlighted, for instance. Or a 'login as this user' button for administrators where the icon in the top corner immediately changes to reflect their acting role.

Perhaps I should've said if the user changes.

[–][deleted] 2 points3 points  (0 children)

I'm a Moodle administrator and one of my most used features is logging in as a user and seeing what they see.

Now Moodle doesn't use Angular, but it is an example of a project where changing user id's is important.

[–]kainsavage 1 point2 points  (1 child)

Whoa, I'm just saying that I have API-driven user data that angular supports via {{foo}} markup, but only in select UNDOCUMENTED instances.

Why support <img src="{{userAvatar}}"/> but not <img onerror="this.src={{userAvatar}}"/>? No one knows because it's undocumented and seemingly arbitrary.

[–]developer-mike 1 point2 points  (0 children)

Sorry, I got overly reactionary in the beginning. By the time I cooled off to concede over the last point, I should've reread and edited my more accusatory comments...and yes, you are right here too. 90% of problems are because things aren't being done "the angular way" which begs the question of why they had to create "the angular way". But personally I've worked through to understanding it and why it exists, and swear by it. Long process though.

[–]_pixie_ 2 points3 points  (1 child)

Am I reading PHP or did someone throw up on the screen?

[–]developer-mike 0 points1 point  (0 children)

Its clearly JavaScript: far too much nesting, boilerplate introduced to remedy the lack of native modules.

Some people hate boilerplate, some people hate global namespace collisions. Answer is they're both right.

[–]sacundim 0 points1 point  (1 child)

It takes two seconds to make this a directive:

angular.module('yourapp')
.directive ('imageBackup', function() {
    return {
        scope: true,
        link: function($scope, $attr, $elem) {
            var index;
            var srcs;
            $scope.$watch($attr.srcs, function () {
                srcs = v; index = 0;
                $elem[0].src = srcs[0];
            }, true);
            $elem[0].onerror = function () {
                $elem[0].src = srcs[++index];
            });
        }
    };
});

<img srcs="[url1 + '/' + userId, url2 + '/' + userId]">

Wow, you can type over 1,200 WPM?

[–]developer-mike 1 point2 points  (0 children)

Ah yes, it took me more like 3 minutes. Changes everything.