Angular2 is being impacted by two components that are causing interference with file events

I am facing an issue with having two instances of a component named FileUploadComponent. The purpose of this component is to listen for file events and emit them to its hosting component using an EventEmitter.

Despite its seemingly simple functionality, when I introduce two instances of the component (Comp1, Comp2) into a template, the first instance seems to receive all events, even from separate components.

To illustrate the issue:

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

In this scenario, Comp1 is receiving events from subsequent instances of the FileUploadComponent, which is unexpected behavior. But why is this happening?

Below are the relevant files for reference:

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 = event.target.files;
    this.filesChanged.emit(this._files);
  }
}

Template for button:

file_upload_button.html

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

Host template:

some_host.html

// 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 erroneously detects itself as responsible, as indicated by the console.log(...) output in the code snippet above. Despite thoroughly reviewing the code for hours, I am unable to provide a logical explanation for this unexpected behavior.


PLUNKER:

http://plnkr.co/edit/7jzjL8dRsCFPUMrVb0I9?p=preview

Answer №1

It appears that the issue is due to having identical id and for attributes on your elements.

To resolve this, make sure to use unique ids:

app/file_upload_button.component.ts

let uniqueId = 0;

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

app/file_upload_button.html

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

Plunker

Answer №2

To provide more assistance, additional information is needed. A plunker demonstration would be helpful. A discrepancy was noticed in the way events are being bound in your some_host.html.

Incorrect binding:

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

Correct binding:

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

The events should be bound to the filesChanged property.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Learn the steps to retrieve a user's profile picture using the Microsoft Graph API and showcase it in a React application

I'm currently working on accessing the user's profile picture through Microsoft's Graph API. The code snippet below demonstrates how I am trying to obtain the profile image: export async function fetchProfilePhoto() { const accessToken = a ...

Is there a way to render an image onto a canvas using an input tag?

Looking to create an image preview using canvas? Upload the image with the input tag and watch it display on canvas. I've experimented with various methods such as using img tags, setting img src for canvas using img tags, and trying onclick function ...

Generate an additional element for each element when clicked, triggering an error warning

When creating a form, I want to display an error message next to each invalid element when the submit button is clicked. Although I am close, the issue is that it adds the span tag twice after the element if two elements are invalid. I need it to be added ...

Data is being fetched successfully but is not being saved or updated in ASP.NET Core 3.1

My issue is reminiscent of a similar inquiry on this post. Despite implementing the suggested solutions, my problem persists as I opted for a slightly different approach in terms of storing data in the database. Employee Model Class public class Empl ...

The inRequestScope feature seems to be malfunctioning and is not functioning as intended

Need help with using inRequestScope in inversifyJS For example: container.bind<ITransactionManager>(Types.MysqlTransactionManager).to(MysqlTransactionManager).inRequestScope() ... container.get<ITransactionManager>(Types.MysqlTransactionMana ...

The JQuery Ajax call returned with a status of 0 and an empty ResponseText

Here is the ajax request I am using: $.ajax({ type: "POST", url: "https://forlineplus.forsa.com.co/projects/validar-redireccion-sio?fup=" + idFup, //contentType: "application/json; charset=utf-8", ...

Leveraging higher-order components in Typescript

I am currently working on integrating react-i18next with Typescript, and I've encountered some challenges in the process. Below is the interface I have set up for the expected props. import * as i18n from 'i18next'; export interface Reac ...

Rails 4 experiences a strange phenomenon where Ajax is triggered twice, resulting in the replacement of

After reviewing other similar questions, it appears that the best approach is to wait for the initial Ajax request to complete before proceeding with the next one. I believed that the following code would handle this situation, but somehow the request is t ...

Discovering Ajax-powered websites Here are some tips on identifying websites

My goal is to determine if a webpage makes AJAX calls. If the webpage is AJAX-based, I will wait for a few seconds to retrieve the content. If it's not AJAX-based, then I won't wait. I attempted the code below, but it didn't yield any resul ...

Effortlessly glide through entire pages using the mouse wheel for seamless scrolling

I provide a seamless full-page scrolling experience using the mouse wheel. However, the scrollIntoView function does not seem to function within the @HostListener('wheel', ['$event']). Here is a snippet from app.component.html file: & ...

Retrieving the recently uploaded image by utilizing file upload functionality and resizing it

Having trouble retrieving the height and width of the currently selected image while uploading images using file upload. What parameters should I pass to the imageCompress function in order to obtain the dimensions of the uploaded image? function onSele ...

What is the ideal location for the jsoncallback to be placed?

function initiate(){ $('#detailsPage').on('pageshow', function(event) { var username = getUrlVars()["username"]; //var username = "studentB"; $.getJSON('http://mywebsite.com/fetchStudent.php?username='+username+&a ...

Discover the location following a designated distance along a direct path connecting two points in the Google Maps API

Using the Google Maps API, I have plotted a straight line from point P1 to point P2. Both points have latitude and longitude coordinates available. I am interested in finding a point (P) along this straight line, located at a specific distance from P1. F ...

Limit pasted content in an Angular contenteditable div

Is there a way to limit the input in a contenteditable div? I am developing my own WYSIWYG editor and want to prevent users from pasting content from external websites and copying styles. I want to achieve the same effect as if the content was pasted into ...

Dynamic property Key in TypeScript

Imagine receiving data from a search engine in the following format: const resultDe = { details_de: "Ein paar Informationen", foo_de:{bar:"barDe"}, code: "1C60" } const resultEn = { details_en: "Some information", fo ...

Guide on extracting the ID within a for loop and incorporating it into a Vue.js function

In order to make an API request, I need to retrieve the id. However, whenever I try to include <a v-on:click="showRecipe({{inf.Id}})">Recipe</a> in my code, the entire page crashes. Removing this line resolves the issue. How can I pass the id ...

Utilize discord.js to create commands with multiple arguments

I'm currently working on creating a command with multiple arguments, like this example: !Poll "This is the title" "This is the description" "This is the time" However, I've encountered an issue where it only recognizes the first 2 arguments. ht ...

The Art of Recording Request and Response in Nest.js

Just diving into Nest.js, I'm working on setting up a basic logger to trace HTTP requests such as : :method :url :status :res[content-length] - :response-time ms Based on what I know, the most suitable place for this would be interceptors. However ...

Dropzone.js: Creating a personalized file explorer to include files that have already been uploaded

Don't worry, this isn't your typical "can't load files from the server" query... I'm looking to allow users to view files on the server in a bootstrap modal and then select specific files. After selection, I want to close the modal and ...

What is the process for utilizing datePipe in an Angular component?

How can I implement DatePipe in my Angular component? This is the code snippet that I am currently using. for (let i = 0; i < this.days.length; i++) { this.storeStart(this.days[i], null, null, null); } I have stored weekdays (Monday to Frid ...