Skip to content

Instantly share code, notes, and snippets.

@Maqsim
Created July 15, 2019 08:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Maqsim/6da63a617e28c87736611baafd61e0df to your computer and use it in GitHub Desktop.
Save Maqsim/6da63a617e28c87736611baafd61e0df to your computer and use it in GitHub Desktop.
Directive that waits for image is available (not 404) for some time and then set image to src="" or background-image: url()
import angular from 'angular';
import { defaults } from 'underscore';
interface IScope extends ng.IScope {
url: string;
backgroundImage: string;
showSpinner: string;
maxRetries: string;
delay: string;
}
/**
* Directive that waits for image is available (not 404) for some time
* and then set image to src="" or background-image: url()
*/
class WaitForImageDirective implements ng.IDirective {
restrict: string = 'A';
scope: any = {
url: '@waitForImage',
backgroundImage: '@waitForImageBackgroundImage',
showSpinner: '@waitForImageShowSpinner',
maxRetries: '@waitForImageMaxRetries',
delay: '@waitForImageDelay'
};
constructor(private $timeout: ng.ITimeoutService) {
'ngInject';
}
public link(scope: IScope, element: JQLite, attrs: ng.IAttributes) {
defaults(scope, {
backgroundImage: 'false',
showSpinner: 'false',
maxRetries: '3',
delay: '500',
});
let suffix: string;
let retry = 0;
let latestRetriedUrl: string;
const setImage = (url: string) => {
if (!element) {
return;
}
if (scope.showSpinner === 'true') {
element.removeClass('wait-for-image_in-progress');
}
if (scope.backgroundImage === 'true') {
element.css('backgroundImage', `url(${url})`);
} else {
element.attr('src', url);
}
};
const image = new Image();
image.onload = () => setImage(latestRetriedUrl);
image.onerror = () => {
if (scope.showSpinner === 'true') {
element.addClass('wait-for-image_in-progress');
}
this.$timeout(() => {
if (retry < parseInt(scope.maxRetries, 10)) {
retry++;
image.src = latestRetriedUrl = scope.url + suffix + Date.now();
}
}, parseInt(scope.delay, 10));
};
attrs.$observe('waitForImage', () => {
retry = 0;
suffix = (scope.url.indexOf('?') > -1 ? '&' : '?') + 't=';
image.src = latestRetriedUrl = scope.url;
setImage(scope.url);
});
}
}
export default angular
.module('app.common.wait-for-image', [])
.directive('waitForImage', ($timeout: ng.ITimeoutService) => new WaitForImageDirective($timeout)).name;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment