3

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: 'tester@wp.pl',
            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.

PawelC
  • 1,128
  • 3
  • 21
  • 47

4 Answers4

4

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(...);
Claudiu Hojda
  • 1,021
  • 9
  • 14
1

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
  );
abdullahkady
  • 1,051
  • 1
  • 8
  • 8
1

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

wFitz
  • 1,266
  • 8
  • 13
  • I use a asp.net core webapi that accepts JSON, don't know if that is your case – wFitz Aug 18 '18 at 20:34
  • Bad request :( See my question – PawelC Aug 18 '18 at 20:38
  • Thats why I added JSON.stringify(user), but that will work if your endpoint accepts JSON. I saw a example of Symfony (https://andrewadcock.com/a-simple-restful-api-tutorial-with-symfony-3/) that expects the params in the url. I don't know what is your case. Try first with postman to see what works. – wFitz Aug 18 '18 at 20:46
  • I add endpoint to postman, set content type to application/x-www-form-urlencoded, send request. Status code 200, my user register correctly. – PawelC Aug 18 '18 at 20:49
0

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.

Werner Hertzog
  • 2,002
  • 3
  • 24
  • 36