PawelC
PawelC

Reputation: 1226

Angular 6 HTTP Client Post - Bad request

I have the following problem. I have a server on which the API is, I send the request to the registration endpoint, but in response I get a 400 Bad Request error, stating that the name, surname, email etc must be filled out. The problem is that they are filled. I miss ideas anymore. My code:

import {Component} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    title = 'Brak tytułu';

    constructor(private http: HttpClient) {
    }

    registerUser() {
        const config = {headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')};
        const user: User = {
            name: 'Pawel',
            surname: 'Tester',
            email: '[email protected]',
            password: 'loremipsum12',
            password_confirm: 'loremipsum12',
            event_id: 1,
        };

        this.http.post('https://myapiserver', user, config).subscribe((res) => {
                console.log(res);
                console.log(user);
            },
            error => {
                console.log(error);
                console.log(user);
            });
    }
}

interface User {
    name: string;
    surname: string;
    email: string;
    password: string;
    password_confirm: string;
    event_id: number;
}

This code works fine, but he is angularJS

    // User create
$scope.createUser = function()
{
    var create_req = $rootScope.reqDefaults;
        create_req.method = 'POST';
        create_req.url = $rootScope.api+'/admin/user';
        create_req.data = $httpParamSerializerJQLike($scope.current);
        create_req.transformRequest = angular.identity;

    // Users list
    $http(create_req)
        .then(function(response){
            $location.path('/users');
            $.notify({
                title: '<strong>Użytkownik utworzony.</strong>',
                message: $scope.current.name+' '+$scope.current.surname+' (ID: '+response.data.id+')'
            },{
                type: 'success'
            });
            return true;
        }, function(response){
            $rootScope.rspError(response.data);
            return false;
        });
};

If i send request to the register endpoint from Postman, all works fine, my user is register correctly :( I set content type to application/x-www-form-urlencoded.

Upvotes: 3

Views: 24803

Answers (4)

Carlos Britos
Carlos Britos

Reputation: 61

Two main problems I see here: the HttpHeaders is missing the Authorization:

const config = {headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
HttpHeaders().set('Authorization': 'Basic ' + credentials);
HttpHeaders().set('Accept':'*/*')
};

where credentials can be: const credentials = btoa("angularUser"+":"+"password"); must be defined in te CORS of the backend to be validated.

Another thing is the body, should be defined as follows:

let user = new URLSearchParams();

user.set('param1', 'value1');
user.set('param2', 'value2');

...

And if is not working, try to change the Content-type from 'application/x-www-form-urlencoded' to 'application/json'. This worked form me at least.

Upvotes: 0

Claudiu Hojda
Claudiu Hojda

Reputation: 1051

The HttpClient from Angular is actually very smart in figuring out what type of content should your request have. By looking into the source code at this line

if (this.body instanceof HttpParams) {
  return 'application/x-www-form-urlencoded;charset=UTF-8';
}

you will see that it will set your required header for you if you set the body as HttpParams. So, the solution to your problem should be:

const body = new HttpParams()
  .set('name', 'foo')
  .set('surname', 'bar')

this.http.post('https://myapiserver', body).subscribe(...);

Upvotes: 4

wFitz
wFitz

Reputation: 1286

this works for me

const config = new HttpHeaders().set('Content-Type', 'application/json')
                                .set('Accept', 'application/json')

this.http.post('https://myapiserver', JSON.stringify(user), 
               { headers: config }).subscrib.....

Hope this helps

EDIT : using new HttpClientModule

const formData = new FormData();

// append your data
formData.append('myKey1', 'some value 1');
formData.append('myKey1', 'some value 2');
formData.append('myKey3', true);

this.httpClient.post('https://myapiserver', formData);

Do NOT set Content-Type header, angular will fix this for you! source : How to force Angular2 to POST using x-www-form-urlencoded

Upvotes: 1

abdullahkady
abdullahkady

Reputation: 1071

Don't set the content headers, which will set them to JSON by default , or set them for JSON like that: application/json

If your API however expects form encoded payload, then you should leave the header just like you have it, but modify the request to send form encoded data like this:

  const body = new HttpParams()
    .set('name', 'Pawel')
    .set('surname', 'Tester');

  this.http.post('https://myapiserver',
    body.toString(),
    config
  );

Upvotes: 1

Related Questions