Unable to upload file in angular2 due to empty Body (FormData)

Attempting to upload a photo with Angular2 to my REST Service (Loopback). The Loopback service has been successfully tested using Postman and is able to accept files with the x-www-form-urlencoded header.

Below is a simplified version of the service method used to send the POST request:

public uploadFile(url: string, file: File): Observable<any> {
  let headers: Headers = new Headers();
  headers.append('Content-Type', 'application/x-www-form-urlencoded');

  let formData = new FormData();
  formData.append('file', file);

  let options: RequestOptionsArgs = { headers: headers };

  return this.http.post(url, formData, options)
  .map((res: any) => (res.text() != "" ? res.json() : {}));
}

It's worth noting that the header has been set to application/x-www-form-urlencoded and the formData containing the file is being sent in the body.

Everything seems fine in Angular up until the http.post request, as the formData is populated with the file and its content is present:

Data before Request

However, during the request, the body appears to be an empty object {}:

Request

It seems like Angular may be attempting to JSON.stringify(formData), which results in an empty object. I have observed many posts using the same method (http.post(url, formData)), so what could potentially be missing here?

Answer №1

To fix the issue, simply deleting the line

headers.append('Content-Type', 'multipart/form-data');
is all that's needed.

For more information, check out this link

Posted on: 2017-08-24

Answer №2

After reading through this informative Stack Overflow post on inspecting FormData and exploring the details provided in this MDN documentation page, it has become apparent that simply outputting FormData in the console results in an empty object {}.

Furthermore, I have discovered that FormData can be utilized directly in a for ... of loop without needing to use entries(). This means that executing for (var p of myFormData) is essentially the same as running

for (var p of myFormData.entries())
.

Answer №3

If you're looking for an alternative approach, one solution is to utilize base64 encoding and perform the conversion on the back-end side: `

const reader = new FileReader();
    reader.readAsDataURL(file);
    let result;
    reader.onload = function () {
      const headers = new Headers();
      headers.append("Content-type","application/x-www-form-urlencoded");
      headers.append('Accept', 'application/json');
      const options = new RequestOptions({ headers: headers });
      return this.http.post(config.serverUrl+"/index.php",
        {
           "file":reader.result}, options)
           .toPromise()
           .then(this.extractData)
           .catch(this.handleError);
    };
    reader.onerror = function (error) {
        console.log('Error: ', error);
    };`

Answer №4

Instead of using formData.append(), I opted for formData.set() in my particular scenario.

Here is an example illustrating this approach:

 uploadSelectedFile(selectedFile: File): Observable<boolean> {
     const endpoint = 'api/file/upload';
     var formData = new FormData();
     formData.set('file', selectedFile);
     return this._http
     .post(endpoint, formData)
     .map(() => { return true; })
     .catch((error) => this.handleError(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

Delegate All Events to the Document

In my current setup, I have over 350 events that look like: $(document).on('click','.removable-init',function(){}); I've noticed a performance issue where some click events are delayed by a fraction of a second. This is happening ...

Show method created by function, substituting the former element on the display

showButtons(1) will show radio buttons for frame number 1, showButtons(400) will display radio buttons for frame number 400. The current code shows all radio buttons for every frame up to 400 HOWEVER, I am aiming for a single set of radio buttons to start ...

Bring in JavaScript files on a global scale in Vue.js 3

Hello, I am facing an issue while trying to import jQuery and THREEJS globally into my Vue.js cli project. Whenever I attempt to import them into my .vue file (like home.vue), I encounter the following error: 'import' and 'export' ma ...

Implementing Laravel's functionality for calculating average ratings with the help of jQuery

In my database, I have two tables named Users and ratings. The Users can give ratings to consultants, and the Ratings table structure is as follows: User_id | consultant_id | rating --------------------------------- 1 1 2 ...

Discover the best places to master AJAX

Although I have come across some related questions here, none of them exactly match mine. I am aware of excellent resources like code-school and code-academy where you can improve your PHP and JS skills by coding directly on the website. However, I am wo ...

Protection of Angular expressions

I have been following the PhoneCat tutorial for AngularJS and found it very helpful up until step 6 where links are generated dynamically from angular expressions: http://localhost:8000/app/{{phone.imageUrl}} Although the tutorial mentions that ngSrc pre ...

Leveraging Amazon IVS Player within Angular

Struggling to integrate the npm version of the amazon-ivs-player with Angular, as it seems optimized for webpack while I am using angular-cli. Following a guide at this link. The issue arises with importing the wasm files in my Angular application: ERROR ...

Unable to precisely reach the very bottom of the scrollbar

When trying to move to the bottom of the scrollbar, I seem to reach a bit higher than the actual bottom. https://i.stack.imgur.com/Vt83t.png Here is my code: ws.onmessage = function (event) { var log = document.getElementById('log') ...

Setting up Angular Universal on an already existing Angular 2 application with the help of the CLI

Encountering obstacles while trying to integrate the universal CLI into an existing Angular 2 application by following the guidelines provided in this link: During the initial command to install angular-universal: npm install body-parser angular2-univers ...

Upgrading Angular from Version 9 to Version 10

Currently facing an issue while attempting to upgrade Angular from version 9 to 10. Despite manually updating the package.json file as below, I am encountering this error message: "@angular/core": "^10.2.5", "@angular/common": ...

Arranging divs using inline-block display. How to adjust the heights consecutively?

After much searching and attempting, I am still unable to achieve a simple task. My goal is to apply display inline-block to some divs while aligning them in a row, similar to the image below: https://i.sstatic.net/iLhLS.png The issue arises when number ...

Learn the process of filtering an array using another array

I have a collection of items set up in the following format. items = [ { id: 1, status : "Active" // Other fields tags : [{val: 'IGM', color: 'light-success' }, {val: 'Gated Out', colo ...

How can I retrieve the array data that was sent as a Promise?

I have a database backend connected to mongoDB using mongoose. There is a controller that sends user data in a specific format: const db = require("../../auth/models"); const User = db.user const addProduct = (req, res) => { User.findOne({ ...

Explore our product gallery with just a simple hover

I am looking to design a product list page with a mouseover gallery similar to the one showcased on [this page][1]. I attempted to use a vertical carousel like the one illustrated in this Fiddle, but unfortunately, it does not function like Zalando and jc ...

What is the method for performing a spelling check on every property within an array of Objects?

I'm working on a program that takes a user input as an argument and then searches for a similar match in an array of objects. The array of objects is retrieved from a database. When the user inputs a name, the search criteria should find objects with ...

Can any function be used to define the path in ExpressJS when setting up GET routes?

I am currently working on developing a web application using node.js. However, I have encountered an issue when trying to use special characters in my navigation path, resulting in the error message "Cannot get /contest". In order to resolve this problem ...

cross-domain ajax response

Imagine a unique scenario that will pique the interest of many developers. You have a JavaScript file and a PHP file - in the JS file, you've coded AJAX to send parameters via HTTP request to the PHP file and receive a response. Now, let's delve ...

I'm at a loss as to why the NestJS provider is showing as undefined in my code

Prisma.service.ts import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common' import { PrismaClient } from '@prisma/client' @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit, OnMod ...

How come I'm facing difficulties when trying to send a post request to my WebApi using AngularJS's POST method?

I've uploaded "mytest.html" to the IIS server, and this project consists of WebApi and AngularJS. However, I am unable to make a correct request to my WebApi. I'm not sure why? 【HTML Code Snippets】 <!DOCTYPE html> <html> ...

Perform a jQuery AJAX GET request while passing the current session information

Is it possible to retrieve the HTML content of another webpage using jQuery, particularly when that page is already signed in? In simpler terms, can we use $.get() to fetch a different page on the same website and transfer the PHP/Javascript cookies with ...