the_critic the_critic - 11 months ago 47
TypeScript Question

Two components interfering file events in Angular2

I have two instances of a component called

, whose responsibility is to listen for file events (it's a simple template that contains a form with a file upload button as shown below) and emit those to its hosting component via an

Simple as it seems, when I add two of those components (Comp1, Comp2) into a template, the first instance of the button on the page seems to receive all events even from separate instances of this particular component.

So to visualize:

Comp1 ---------------------- / EventEmitter Fired
Comp2 -- File uploaded ----- / -------

Here you can see that
receives an event from subsequent instances of this
, why is that ?

Here are the files:

file_upload_button.component.ts (Component Decorator omitted for brevity)

export class FileUploadButtonComponent {

@Output() filesChanged = new EventEmitter<File[]>();
private _files: File[];

fileUpload(event: FileReaderEvent) {

console.log(this); // !!! ====> this already triggers in the wrong component!

this._files =;

Template for button:


<input type="file" multiple name="file" (change)="fileUpload($event)" id="file"/>

Host template:


// first instance
<file-upload-button (filesChanged)="filesChangedFunc($event)"><file-upload-button>
// second instance
<file-upload-button (filesChanged)="anotherFilesChangedFunc($event)"><file-upload-button>

When I click the second button, the first instance sees itself responsible, the
in the above code mentions that. Having gone over this code for several hours I have no sane explanation for what is happening here.


Answer Source

That's because you have the same id and for respectively on your elements.

You have to use unique id:


let uniqueId = 0;

  selector: 'file-upload-button',
  templateUrl: 'app/file_upload_button.html',
  styleUrls: [ 'app/file_upload_button.css' ]
export class FileUploadButtonComponent {
  id = `file-upload-${uniqueId++}`;


<input type="file" [name]="'name' + id" [id]="id" .../>
<label [attr.for]="id" ...