Uploading a file with HTML file input leads to the destruction of the parent component

Consider a straightforward angular component structured like this:

import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';

@Component({
  selector: 'app-upload',
  templateUrl: './upload.component.html',
  styleUrls: ['./upload.component.scss']
})
export class UploadComponent implements OnInit {

  @Input() testo?: string;

  @Output() valueChange = new EventEmitter();

  constructor() {
  }

  ngOnInit(): void {

  }

  inputChange(event: any) {
   this.valueChange.emit(event);
  }

  ngOnChanges(event: any): void{
    console.log(event);
  }

  ngOnDestroy(event: any): void {
      console.log(event);
      console.log("Destroy");
  }
}

And the structure of the HTML is as follows:

<input #fileInput
       id="importFile"
       type="file"
       style="display: none"
       (change)="inputChange($event)" />

<button type="button"
        mat-raised-button
        color="accent"
        (click)="fileInput.click()">
    {{this.testo}}
</button>

If a file is selected and confirmed in the file explorer, everything functions correctly. However, if the input window is closed or canceled, there is a brief freeze in Chrome/Mozilla browsers followed by the entire component being destroyed (as indicated by logging).

A major issue arises when the component is within a popup (a component opened as a popup), leading to the destruction of the entire component and subsequent closure of the popup.

In the past, this code worked flawlessly. Interestingly, other applications utilizing input files also experience the "small freeze" issue (some examples can be found on StackBlitz).

Thank you.

Answer №1

Eliminate ngOnDestroy with Arguments.

The ngOnDestroy lifecycle hook should not accept any parameters. Update the definition of your ngOnDestroy method to:

ngOnDestroy(): void {
    console.log("Destroy");
}

If you need to clean up operations before the component is destroyed, handle them within this method.

If the component is used as a popup, ensure proper management of the popup. If the popup closes when the file input is canceled, make sure the popup closure does not unexpectedly destroy the component.

Answer №2

It seems like the input file is triggering a cancel event.

No indication of this was found on childrens, but it does trigger my "cancel()".

I made a rough switch to the cancel code from:

  cancel(event:any) {
          this.dialogRef.close({type: CallbackDetailsState.CANCEL} as DetailsCallback );
  }

to

  cancel(event:any) {
      if (event && event.target && event.target.toString() == "[object HTMLInputElement]") {
          console.log("Prevent Close");
      } else {
          this.richiesta.note = '';
          this.dialogRef.close({type: CallbackDetailsState.CANCEL} as DetailsCallback );
      }
  }

where cancel is activated as an action from a form app, for example:

(updateForm)="updateForm($event)"
(saveForm)="saveOgg($event)"
(cancel)="cancel($event)">

the - unattended - generated event is:

Event {isTrusted: true, type: 'cancel', target: input#importFile, currentTarget: null, eventPhase: 0, …}
isTrusted: true
bubbles: true
cancelBubble: false
cancelable: false
composed: false
currentTarget: null
defaultPrevented: false
eventPhase: 0
returnValue: true
srcElement: input#importFile
target: input#importFile
timeStamp: 7451.100000143051
type: "cancel"

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

What is the collection of types that accept a parameterized argument?

I am working with an item interface that looks like this: interface Item<Href extends string> { href: Route<Href> } My goal is to create a component that accepts a list of these Item objects as a single property: interface Props { items: I ...

What sets Import apart from require in TypeScript?

I've been grappling with the nuances between import and require when it comes to using classes/modules from other files. The confusion arises when I try to use require('./config.json') and it works, but import config from './config.json ...

Angular - Customizing button bindings for various functions

As a newcomer to Angular and TypeScript, I am faced with the task of creating a customizable button that can display text, an icon, or both. For example: button-icon-text-component.html <button> TEST BUTTON </button> app.component.html & ...

Using GraphQL to set default values in data within a useEffect hook can lead to never

Here's the code snippet that I'm working with: const [localState, setLocalState] = useState<StateType[]>([]); const { data = { attribute: [] }, loading } = useQuery<DataType>(QUERY, { variables: { id: client && client.id ...

Triggering the detection of changes even when the value linked to remains the same

I'm facing an issue with a component that is supposed to react to changes in input controls by reformatting the input and removing certain characters. If the removed character corresponds to the previous value, the component fails to detect any change ...

Implementing universal style updates in Angular 4

I am looking to integrate Bootstrap with Angular4 and also need to support RTL styling. Currently, there is no official RTL support in Bootstrap, but there are various GitHub projects offering patches for this. In the past, I used jQuery to dynamically cha ...

Tips for showcasing saved images in Spring Boot with Angular 4

I am currently utilizing Spring Boot in combination with Angular 4. The issue I am facing involves uploading an image to the project location. However, upon attempting to view the uploaded image, it does not display correctly and instead throws an error. H ...

Developing a universal SDK wrapper for Firebase services (Firestore, Cloud Storage, and additional functionalities)

Currently, I am on the quest to discover an abstraction that can facilitate the seamless operation of Firebase products (specifically Firestore, Storage, and Analytics) across any platform (be it React Native, React, or Node.js). While considering the REST ...

Error: Component with nested FormGroup does not have a valid value accessor for form control in Angular

In my setup, the parent component is utilizing a FormGroup and I am expecting the child components to notify any changes in value back to the parent. To achieve this, I am trying to implement NG_VALUE_ACCESSOR in the child component so that it can act like ...

Asynchronous binding within a dynamic form

After following the Angular guide on creating dynamic forms, I have developed a series of classes to generate forms dynamically. While this approach is effective, it doesn't offer much efficiency unless the forms can be dynamically generated based on ...

What could be the root of this Typescript error related to the SX prop?

I found this code snippet on https://mui.com/system/the-sx-prop/ and tried implementing it, but encountered a TypeScript error. sx={(theme: Theme): SxProps<Theme> | undefined => ({ ...theme.typography.body, color: theme.palette.primary.main, ...

How to reset the width of custom-sized table columns in a prime-ng p-table

Is there a method to reset the column widths of a p-table in primeng that have been set with 'resizableColumns="true"'? I want to provide users with the ability to revert back to the original sizes. ...

What is the best way to highlight rows for expansion in a primeng table?

Currently, I am experimenting with primeng table row expansion by following this specific example: https://stackblitz.com/edit/github-7gxyuy?file=src/app/app.component.html Despite my efforts to have each expansion row selected individually, I encountered ...

Exploring Angular 10 Formly: How to Retrieve a Field's Value within a Personalized Formly Wrapper

Utilizing Angular 10, I have a formly-form with a select-field named session. This select field provides options from which to choose a dndSession. Each option holds key-value pairs within an object. I want to add a button next to the select-field that tr ...

Displaying a Router Component within an Angular 4 Interface

Is there a way to display a router component without explicitly calling the router.navigate method? I have a method that currently navigates like this: public onClickEdit(id: number): void { this.router.navigate(['...', '...', &ap ...

Removing item from Angular service

Within my Angular 2 application, I have created a service called events.service.ts: const EVENTS = { 1512205360: { event: 'foo' }, 1511208360: { event: 'bar' } } @Injectable() export class EventsService { getEvents() ...

Retain the previous value in the input field when using a shared form for both updating and adding data

I've been utilizing a standard form for adding and updating data. The issue I'm facing is that when I click on the edit form, make changes to the input field values, but then close the form without clicking on the update button - the previous val ...

Tips for avoiding errors when a data field is missing in Angular 2

Presently, I am in the process of developing an application using Angular 2 and integrating it with a database. However, a particular line of code is causing an error: <span class="col-sm-6">{{workorder.timeWindowAppointment.date}}</span> The ...

Tips for preventing code duplication across various components in Angular 5

Within my angular application, there exist multiple components. Interestingly, two of these components share almost identical code, except for one component that includes additional button tags with unique logic while the rest of the code remains consist ...

The 'export '__platform_browser_private__' could not be located within the '@angular/platform-browser' module

I have encountered an issue while developing an angular application. Upon running ng serve, I am receiving the following error in ERROR in ./node_modules/@angular/http/src/backends/xhr_backend.js 204:40-68: "export 'platform_browser_private' w ...