Skip to content
This repository has been archived by the owner on Oct 1, 2023. It is now read-only.

Only load items once (reuse promise) #10

Merged
merged 1 commit into from
Jan 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 36 additions & 28 deletions angular-load.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,60 @@
angular.module('angularLoad', [])
.service('angularLoad', ['$document', '$q', '$timeout', function ($document, $q, $timeout) {

function loader(createElement) {
var promises = {};

return function(url) {
if (typeof promises[url] === 'undefined') {
var deferred = $q.defer();
var element = createElement(url);

element.onload = element.onreadystatechange = function (e) {
$timeout(function () {
deferred.resolve(e);
});
};
element.onerror = function (e) {
$timeout(function () {
deferred.reject(e);
});
};

promises[url] = deferred.promise;
}

return promises[url];
};
}

/**
* Dynamically loads the given script
* @param src The url of the script to load dynamically
* @returns {*} Promise that will be resolved once the script has been loaded.
*/
this.loadScript = function (src) {
var deferred = $q.defer();
this.loadScript = loader(function (src) {
var script = $document[0].createElement('script');
script.onload = script.onreadystatechange = function (e) {
$timeout(function () {
deferred.resolve(e);
});
};
script.onerror = function (e) {
$timeout(function () {
deferred.reject(e);
});
};

script.src = src;

$document[0].body.appendChild(script);
return deferred.promise;
};
return script;
});

/**
* Dynamically loads the given CSS file
* @param href The url of the CSS to load dynamically
* @returns {*} Promise that will be resolved once the CSS file has been loaded.
*/
this.loadCSS = function (href) {
var deferred = $q.defer();
this.loadCSS = loader(function (href) {
var style = $document[0].createElement('link');

style.rel = 'stylesheet';
style.type = 'text/css';
style.href = href;
style.onload = style.onreadystatechange = function (e) {
$timeout(function () {
deferred.resolve(e);
});
};
style.onerror = function (e) {
$timeout(function () {
deferred.reject(e);
});
};

$document[0].head.appendChild(style);
return deferred.promise;
};
return style;
});
}]);
})();
2 changes: 1 addition & 1 deletion angular-load.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion angular-load.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"node": ">=0.10.0"
},
"scripts": {
"test": "grunt test"
"test": "grunt test",
"build": "grunt build"
}
}
12 changes: 12 additions & 0 deletions tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ describe('service angularLoad', function () {
$timeout.flush();
expect(rejected).toBeTruthy();
});

it('should only append the script tag once', function() {
angularLoad.loadScript('https://www.test.org/somescript.js');
angularLoad.loadScript('https://www.test.org/somescript.js');
expect(mockDocument.body.appendChild.calls.all().length).toBe(1);
});
});

describe('#loadCSS', function() {
Expand Down Expand Up @@ -97,5 +103,11 @@ describe('service angularLoad', function () {
$timeout.flush();
expect(rejected).toBeTruthy();
});

it('should only append the stylesheet link once', function() {
angularLoad.loadCSS('https://www.test.org/styles.css');
angularLoad.loadCSS('https://www.test.org/styles.css');
expect(mockDocument.head.appendChild.calls.all().length).toBe(1);
});
});
});