Skip to content

Commit 0f30a33

Browse files
committed
Fix: file uploader valueChanges event to fire for dragAndDrop
Signed-off-by: anemonetea <[email protected]>
1 parent d6009ab commit 0f30a33

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

src/file-uploader/file-uploader.component.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ export class FileUploader implements ControlValueAccessor {
172172
}
173173

174174
/**
175-
* Specifies the property to be used as the return value to `ngModel`
175+
* Specifies the property to be used as the return value to `ngModel` and reactive forms.
176+
* Updates `this.files`.
176177
*/
177178
get value(): Set<FileItem> {
178179
return this.files;
@@ -241,35 +242,37 @@ export class FileUploader implements ControlValueAccessor {
241242
event.stopPropagation();
242243
event.preventDefault();
243244

244-
const transferredFiles = Array.from(event.dataTransfer.files);
245+
const transferredFiles: Array<File> = Array.from(event.dataTransfer.files);
246+
const newFiles = new Set<FileItem>(this.files);
245247

246248
transferredFiles.filter(({ name, type }) => {
247249
// Get the file extension and add a "." to the beginning.
248250
const fileExtension = name.split(".").pop().replace(/^/, ".");
249251
// Check if the accept array contains the mime type or extension of the file.
250252
return this.accept.includes(type) || this.accept.includes(fileExtension) || !this.accept.length;
251253
}).forEach(file => {
252-
if (!this.files.size || this.multiple) {
254+
if (!newFiles.size || this.multiple) {
253255
const fileItem = this.createFileItem(file);
254-
this.files.add(fileItem);
256+
newFiles.add(fileItem);
255257
}
256258
});
257259

258-
this.filesChange.emit(this.files);
259-
this.value = this.files;
260+
this.value = newFiles;
261+
this.filesChange.emit(newFiles);
260262
this.dragOver = false;
261263
}
262264

263265
removeFile(fileItem) {
264-
let shouldEmit = true;
265-
if (this.files) {
266-
shouldEmit = this.files.has(fileItem);
267-
this.files.delete(fileItem);
266+
// Deleting an item from this.files removes the <ibm-file> component,
267+
// which triggers its ngOnDestroy(), which fires the (remove) event again.
268+
// So, (remove) may double-fire and we need to handle it here.
269+
if (this.files && this.files.has(fileItem)) {
270+
const newFiles = new Set<FileItem>(this.files);
271+
newFiles.delete(fileItem);
272+
this.filesChange.emit(newFiles);
273+
this.value = newFiles;
268274
}
269275
this.fileInput.nativeElement.value = "";
270-
if (shouldEmit) {
271-
this.filesChange.emit(this.files);
272-
}
273276
}
274277

275278
public isTemplate(value) {

src/file-uploader/file-uploader.stories.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, Input, OnInit } from "@angular/core";
1+
import { Component, Input, OnDestroy, OnInit } from "@angular/core";
22
import { storiesOf, moduleMetadata } from "@storybook/angular";
33

44
import { action } from "@storybook/addon-actions";
@@ -20,6 +20,7 @@ import { NotificationService } from "../notification/notification.service";
2020
import * as fileType from "file-type";
2121
import { DocumentationModule } from "../documentation-component/documentation.module";
2222
import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms";
23+
import { Subject, Subscription } from "rxjs";
2324

2425
@Component({
2526
selector: "app-file-uploader",
@@ -65,7 +66,7 @@ class FileUploaderStory {
6566
}
6667

6768
onUpload() {
68-
this.files.forEach(fileItem => {
69+
this.files.forEach((fileItem: any) => {
6970
if (!fileItem.uploaded) {
7071
if (fileItem.file.size < this.maxSize) {
7172
fileItem.state = "upload";
@@ -177,7 +178,7 @@ class DragAndDropStory {
177178
}
178179

179180
onUpload() {
180-
this.files.forEach(fileItem => {
181+
this.files.forEach((fileItem: any) => {
181182
if (!fileItem.uploaded) {
182183
if (fileItem.file.size < this.maxSize) {
183184
fileItem.state = "upload";
@@ -250,14 +251,14 @@ class NgModelFileUploaderStory {
250251
}
251252

252253
onUpload() {
253-
this.model.forEach(fileItem => {
254+
this.model.forEach((fileItem: any) => {
254255
if (!fileItem.uploaded) {
255256
if (fileItem.file.size < this.maxSize) {
256257
fileItem.state = "upload";
257258
setTimeout(() => {
258259
fileItem.state = "complete";
259260
fileItem.uploaded = true;
260-
console.log(fileItem);
261+
console.log("Uploaded file:", fileItem);
261262
}, 1500);
262263
}
263264

@@ -314,7 +315,7 @@ class NgModelFileUploaderStory {
314315
</form>
315316
`
316317
})
317-
class ReactiveFormsStory implements OnInit {
318+
class ReactiveFormsStory implements OnInit, OnDestroy {
318319
static notificationCount = 0;
319320
public formGroup: FormGroup;
320321
public disabledFormGroup: FormGroup;
@@ -331,6 +332,7 @@ class ReactiveFormsStory implements OnInit {
331332
@Input() disabled = false;
332333

333334
protected maxSize = 500000;
335+
private subscribers: Subscription[] = [];
334336

335337
constructor(
336338
protected notificationService: NotificationService,
@@ -347,6 +349,15 @@ class ReactiveFormsStory implements OnInit {
347349
files: new FormControl(new Set<any>(), [Validators.required])
348350
});
349351
this.disabledFormGroup.disable();
352+
353+
const sub = this.formGroup.valueChanges.subscribe(this.fileChangesObserver);
354+
this.subscribers.push(sub);
355+
}
356+
357+
ngOnDestroy() {
358+
this.subscribers.forEach(sub => {
359+
sub.unsubscribe();
360+
});
350361
}
351362

352363
onUpload() {
@@ -357,6 +368,7 @@ class ReactiveFormsStory implements OnInit {
357368
setTimeout(() => {
358369
fileItem.state = "complete";
359370
fileItem.uploaded = true;
371+
console.log("Uploaded file:", fileItem);
360372
}, 1500);
361373
}
362374

@@ -371,6 +383,10 @@ class ReactiveFormsStory implements OnInit {
371383
}
372384
});
373385
}
386+
387+
private fileChangesObserver = (value: {files: Set<File>}) => {
388+
console.log("files:", value.files);
389+
}
374390
}
375391

376392

0 commit comments

Comments
 (0)