Skip to content

Commit

Permalink
feat(service): add hooks support
Browse files Browse the repository at this point in the history
  • Loading branch information
gshokanov committed Mar 27, 2020
1 parent 2098d2d commit a098173
Showing 1 changed file with 54 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ import {

const LOG_PREFIX = '@angular-extensions/elements';

export type Hook = (tag: string) => Promise<void> | void;

export interface HooksConfig {
beforeLoad?: Hook;
afterLoad?: Hook;
}

export interface ElementConfig {
tag: string;
url: string;
isModule?: boolean;
loadingComponent?: Type<any>;
errorComponent?: Type<any>;
preload?: boolean;
hooks?: HooksConfig;
}

@Injectable({
Expand Down Expand Up @@ -49,7 +57,12 @@ export class LazyElementsLoaderService {
? newConfig.preload
: this.options.preload;
if (shouldPreload) {
this.loadElement(newConfig.url, newConfig.tag, newConfig.isModule);
this.loadElement(
newConfig.url,
newConfig.tag,
newConfig.isModule,
newConfig.hooks
);
}
}
});
Expand All @@ -65,11 +78,16 @@ export class LazyElementsLoaderService {
configs = this.configs.filter(config => tags.includes(config.tag));
}
configs.forEach(config =>
this.loadElement(config.url, config.tag, config.isModule)
this.loadElement(config.url, config.tag, config.isModule, config.hooks)
);
}

loadElement(url: string, tag: string, isModule?: boolean): Promise<void> {
loadElement(
url: string,
tag: string,
isModule?: boolean,
hooksConfig?: HooksConfig
): Promise<void> {
const config = this.getElementConfig(tag);

if (!url) {
Expand Down Expand Up @@ -99,9 +117,23 @@ export class LazyElementsLoaderService {
script.type = 'module';
}
script.src = url;
script.onload = notifier.resolve;
script.onload = () => {
if (hooksConfig?.afterLoad) {
this.handleHook(hooksConfig.afterLoad, tag)
.then(notifier.resolve)
.catch(notifier.reject);
} else {
notifier.resolve();
}
};
script.onerror = notifier.reject;
document.body.appendChild(script);
if (hooksConfig?.beforeLoad) {
this.handleHook(hooksConfig.beforeLoad, tag)
.then(() => document.body.appendChild(script))
.catch(notifier.reject);
} else {
document.body.appendChild(script);
}
}

return this.registry.get(this.stripUrlProtocol(url));
Expand All @@ -123,6 +155,23 @@ export class LazyElementsLoaderService {
private stripUrlProtocol(url: string): string {
return url.replace(/https?:\/\//, '');
}

private isPromise<T>(obj: T | Promise<T>): obj is Promise<T> {
return typeof (obj as any).then === 'function';
}

private handleHook(hook: Hook, tag: string): Promise<void> {
try {
const result = hook(tag);
if (this.isPromise(result)) {
return result;
} else {
return Promise.resolve();
}
} catch (err) {
return Promise.reject(err);
}
}
}

interface Notifier {
Expand Down

0 comments on commit a098173

Please sign in to comment.