Skip to content

Commit

Permalink
Add onLoad and onError event emitters (#128)
Browse files Browse the repository at this point in the history
* Add onLoad and onError event emitters

Emit events on onload and onerror of the <img> underlying <cl-image>.

Update photo_album sample.

Fixes #81
  • Loading branch information
eitanp461 authored Jan 28, 2018
1 parent ebbff80 commit 590c927
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@
[public-id]="publicId"
type="facebook"
angle="20"
(onLoad)="onLoadImage($event)"
>
<cl-transformation effect="art:hokusai"></cl-transformation>
<cl-transformation border="3px_solid_rgb:00390b" radius="20"></cl-transformation>
</cl-image>
<cl-image
public-id="non-existing"
(onError)="onErrorImage($event)"
>
</cl-image>
</a>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ export class PhotoListComponent implements OnInit {
}

changePublicId() {
this.publicId = (this.publicId === 'officialchucknorrispage') ? 'billclinton' : 'officialchucknorrispage';
this.publicId = (this.publicId === 'officialchucknorrispage') ? 'billclinton' : 'officialchucknorrispage';
}

onLoadImage(success) {
console.log('On load', success);
}
onErrorImage(err) {
console.log('On error!!', err);
}
}
47 changes: 46 additions & 1 deletion src/cloudinary-image.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,52 @@ describe('CloudinaryImage', () => {
});
});

describe('event emitters', () => {
let onImageLoad;
let onImageError;
let des: DebugElement; // the elements w/ the directive

@Component({
template: `<cl-image id="image1" [public-id]="publicId"></cl-image>`
})
class TestComponent {
publicId: string = 'sample';
}

let fixture: ComponentFixture<TestComponent>;

beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [CloudinaryTransformationDirective, CloudinaryImage, TestComponent],
providers: [{ provide: Cloudinary, useValue: localCloudinary }]
}).createComponent(TestComponent);

fixture.detectChanges(); // initial binding
// all elements with an attached CloudinaryImage
des = fixture.debugElement.query(By.directive(CloudinaryImage));
onImageLoad = jasmine.createSpy('onImageLoad');
onImageError = jasmine.createSpy('onImageError');
des.componentInstance.onLoad.subscribe(onImageLoad);
des.componentInstance.onError.subscribe(onImageError);
});

it('calls the onLoad callback when image loads successfully', () => {
// Simulate the load event
const img = des.children[0].nativeElement as HTMLImageElement;
img.dispatchEvent(new Event('load'));
expect(onImageLoad).toHaveBeenCalled();
expect(onImageError).not.toHaveBeenCalled();
});

it('calls the onError callback when image fails to load', () => {
// Simulate the error event
const img = des.children[0].nativeElement as HTMLImageElement;
img.dispatchEvent(new CustomEvent('error', { detail: 'Eitan was here' }));
expect(onImageLoad).not.toHaveBeenCalled();
expect(onImageError).toHaveBeenCalled();
});
});

describe('responsive images with nested transformations using the cld-responsive attribute', () => {
@Component({
template: `<cl-image cld-responsive id="image1" public-id="responsive_sample.jpg">
Expand Down Expand Up @@ -254,5 +300,4 @@ describe('CloudinaryImage', () => {
/c_scale,l_text:roboto_25_bold:SDK,w_300\/e_art:hokusai\/f_auto\/responsive_sample.jpg/));
});
});

});
34 changes: 23 additions & 11 deletions src/cloudinary-image.component.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import {
Component,
ElementRef,
Input,
ContentChildren,
QueryList,
AfterViewInit,
OnInit,
OnChanges,
SimpleChanges,
OnDestroy,
Component,
ElementRef,
EventEmitter,
Input,
Output,
ContentChildren,
QueryList,
AfterViewInit,
OnInit,
OnChanges,
SimpleChanges,
OnDestroy
} from '@angular/core';
import { Cloudinary } from './cloudinary.service';
import { CloudinaryTransformationDirective } from './cloudinary-transformation.directive';
Expand All @@ -24,6 +26,9 @@ export class CloudinaryImage
@ContentChildren(CloudinaryTransformationDirective)
transformations: QueryList<CloudinaryTransformationDirective>;

@Output() onLoad: EventEmitter<boolean> = new EventEmitter(); // Callback when an image is loaded successfully
@Output() onError: EventEmitter<boolean> = new EventEmitter(); // Callback when an image is loaded with error

observer: MutationObserver;

constructor(private el: ElementRef, private cloudinary: Cloudinary) {}
Expand Down Expand Up @@ -55,7 +60,7 @@ export class CloudinaryImage
}

ngOnDestroy(): void {
if (this.observer) {
if (this.observer && this.observer.disconnect) {
this.observer.disconnect();
}
}
Expand All @@ -75,6 +80,13 @@ export class CloudinaryImage
}
const nativeElement = this.el.nativeElement;
const image = nativeElement.children[0];
// Add onload and onerror handlers
image.onload = e => {
this.onLoad.emit(e);
}
image.onerror = e => {
this.onError.emit(e);
}
const options = this.cloudinary.toCloudinaryAttributes(
nativeElement.attributes,
this.transformations
Expand Down
2 changes: 1 addition & 1 deletion src/cloudinary-video.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class CloudinaryVideo
}

ngOnDestroy(): void {
if (this.observer) {
if (this.observer && this.observer.disconnect) {
this.observer.disconnect();
}
}
Expand Down

0 comments on commit 590c927

Please sign in to comment.