Angular FormData fails to append and upload files

I am attempting to use FormData in order to upload a file through an HTTP Request. Here is the HTML code:

<ng-template #displayApp>
    <div class="display flex justify-content-center">
        <div >
            <p-fileUpload 
            chooseLabel="Select First File"
            [showUploadButton]="false"
            [showCancelButton]="false"        
            (onSelect)="checkFilesSelected()"
            (onRemove)="checkFilesSelected()"
            #originalFile>
            </p-fileUpload>
        </div>

        <div style="margin: 0 20px;"></div>

        <div >
            <p-fileUpload 
            chooseLabel="Select Second File"
            [showUploadButton]="false"
            [showCancelButton]="false"             
            (onSelect)="checkFilesSelected()"
            (onRemove)="checkFilesSelected()"
            #revisedFile>
            </p-fileUpload>
        </div>
    </div>
    <div style="margin-bottom: 20px;"> </div>
    <div class="display flex justify-content-center">
        <p-button [disabled]="!areFilesSelected" (click)="onUpload()">Compare Files</p-button>
    </div>
</ng-template>

I am choosing two files and attempting to upload both files together with a single call to keep them synchronized.

Here is my component's TS file:

  @ViewChild('firstFile') firstFile!: FileUpload;
  @ViewChild('secondFile') secondFile!: FileUpload;

onUpload() {
    console.log("File upload called",);

    const originalFiles: File = this.originalFile.files[0]
    const revisedFiles: File[] = this.revisedFile.files;
    let formData: FormData = new FormData();

    console.log("First ",originalFiles, originalFiles.name)
    debugger;

    formData.append('First', originalFiles)
    console.log("Form Data ", formData)

    let uploadUrl = new URL('baseURL');

    uploadUrl.searchParams.append('First',"first");
    uploadUrl.searchParams.append('Second',"second");  

    this.http.post(uploadUrl.toString(), formData).subscribe(
      response => {
        console.log('File uploaded successfully:', response);
      },
      error => {
        console.error('Error uploading file:', error);
      }
    );
  }

I have noticed that originalFiles gets populated with file details. However, when I try to append it to formData, it remains empty without throwing any exceptions. The formData appears empty when viewed on the console. Any assistance on this issue would be greatly appreciated.

I attempted to change the data type to File instead of FileUpload, but it did not resolve the issue. Using event.Files[0] appends the file correctly. I am unsure how to merge this event into a single one for file uploads.

Answer №1

When working with form data in Angular, it is crucial to ensure that the enctype header is properly set. Checking the values within the FormData can be done using the

entries method.</p>
<pre><code>onUpload() {
  console.log("Initiating file upload");

  const originalFiles: File = this.originalFile.files[0];
  const revisedFiles: File[] = this.revisedFile.files;
  
  let formData: FormData = new FormData();
  formData.append('First', originalFiles);

  // Logging each entry in the formData
  for (const [key, value] of formData.entries()) {
    console.log(`${key}: ${value}`);
  }

  let uploadUrl = new URL('baseURL');
  uploadUrl.searchParams.append('First', "first");
  uploadUrl.searchParams.append('Second', "second");

  const headers = new HttpHeaders({ 'enctype': 'multipart/form-data' });

  this.http.post(uploadUrl.toString(), formData, { headers: headers }).subscribe(
    response => {
      console.log('File uploaded successfully:', response);
    },
    error => {
      console.error('Error uploading file:', error);
    }
  );
}

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

Unraveling the Mystery of @Input and @Output Aliases in Angular 2

After researching about the @Input() and @Output() decorators, I discovered that we have the option to use an alias instead of the property name for these decorators. For example: class ProductImage { //Aliased @Input('myProduct') pro ...

Is there a way to ensure in TypeScript that a generic type includes a property that implements a particular method?

To better explain my query, let me provide an illustration. Suppose I aim to create a method that accepts three parameters, as shown below: customFilter<T>(values: T[], filterString: string, propName: string) any[] { return values.filter((value) ...

Can someone confirm if I am importing this png file correctly? I am encountering an error with Vite, here is my code

Error: TypeScript+ React + Vite [plugin:vite:import-analysis] Failed to find import "./assets/heropic.png" in "src\components\Hero.tsx". Are you sure the file exists? Hello fellow developers! I am new to working with react and typescript. Curren ...

Defining a structure for an entity in which its attributes distinguish between different data types and an array combination

I strongly believe that the best way to showcase this concept is through a clear example: enum EventType { A, B, C }; type MyEvent = [EventType.A, number] | [EventType.B, string] | [EventType.C, number, string]; const eventsGrouped: Record<Event ...

Can you explain the significance of the '#' symbol within the input tag?

I was reading an article about Angular 2 and came across a code snippet that uses <input type='text' #hobby>. This "#" symbol is being used to extract the value typed into the textbox without using ngModal. I am confused about what exactly ...

Initializing various objects on the same interface type array in one line

Is there a way to inline initialize an array of the interface type IFooFace in TypeScript with different specific implementations, similar to how it can be done in C#? Or do I have to initialize my objects before the array and then pass them in? In C#, th ...

Building Individual Elements in Angular 2

My task involves creating two distinct components in Angular 2, the Users component and the Clients component. These components are not nested and do not have any relationship. To call these components separately, I typically use main.ts as the main entry ...

When is the best time in the redux flow to utilize methods for displaying notifications, such as toasts?

As I develop my angular2 app using ngrx/store, I am wondering at which point in the redux lifecycle I should trigger methods to display notifications (toasts). My initial thought is to handle this in side effects (utilizing ngrx/effects). @Effect({ dispa ...

Connecting Angularfire2 with Firestore for advanced querying

Glad you stopped by! Currently, I have two Firestore Collections set up in my Angularfire2 application. One consists of "Clients", while the other contains "Jobs". Each client can have multiple jobs assigned to them, and vice versa. I've been workin ...

Angular2 - Incorporating a New Attribute

I am working with the following Angular2 code: <ngx-datatable-column prop="id" name="ID"> <template ngx-datatable-cell-template let-row="row" let-value="value"> <a [routerLink]="['/devicedtls',r ...

Despite subscribing, the Ngxs @Select decorator is still returning undefined values

I am attempting to access and read the labels stored in the state file. Displayed below is my state file: export class LabelStateModel { labels: LabelConfig = {}; } @State<LabelStateModel>({ name: 'labels', defaults: { labels: { ...

Best practices for organizing API Services using TypeScript and Next.js Server Actions

My product-actions/index file contains various server actions such as createProduct and getProductAssets, each of which verifies the user session before processing the request. I am looking for a way to check the session validity only once and then procee ...

TypeORM's one-to-many relationship alters the primary entity once the relationship has been established

When working on my side project, I decided to implement a friend request system using NestJS + TypeORM for the backend. However, I encountered a peculiar issue where every time I tried to associate a Friend entity with a specific user, the target field of ...

Headers cannot be modified after they have been sent to the client in Node.js and Angular

I am working on developing login and registration services using Nodejs Express. Every time I make a request in postman, I consistently encounter the same error: https://i.stack.imgur.com/QZTpt.png Interestingly, I receive a response in postman (register ...

Navigating with Angular's router occurs before the guard is fully completed

Within my Angular 8 application, the routing file is structured as below: const myRoutes: Routes = [ {path: '', component: FirstComponent , canActivate: [RegistrationSrcdGuard]}, {path: 'FirstComponent ', component: FirstCompon ...

Experimenting with throws using Jest

One of the functions I'm testing is shown below: export const createContext = async (context: any) => { const authContext = await AuthGQL(context) console.log(authContext) if(authContext.isAuth === false) throw 'UNAUTHORIZED' retu ...

When in development mode, opt for the unminified version of the library in Web

My TypeScript project utilizes a forked version of the apexcharts npm package. When building the project with webpack in development mode, I want to use the unminified version of the apex charts library. However, for production, I prefer to stick with the ...

What is the best way to execute a function while utilizing its default options?

I am working on a project that involves a drop down box and an input box. Here is the HTML code for the drop-down box: <select #select id="id" class="class" (change)="onChange($event)"> <option value="1"> 1 </option> <option v ...

Managing state on the login page functions properly, although there is a minor inconvenience of having to click the login button twice after entering the username and password

In Login.tsx, I store user/pass info in a useState called login and pass it up to App.tsx. I then store the access property from login useState to access useState inside App.tsx. While this does technically work, there is an issue where it seems to be one ...

"Exploring the dynamic duo: Algolia integration with Angular

I've been following a tutorial on implementing instantsearchjs in my website, which can be found here. Everything is set up correctly and I can query for results in .JSON format from my website. However, I'm having trouble figuring out how to r ...