0

I set up a simple Ionic 5 application and a NestJS backend. Now I want to send a POST request from my application to my backend, but I always get the following error message in the browser console:

Object {headers: {…}, status: 500, statusText: "Internal Server Error", url: "http://localhost:3000/api/users", ok: false, name: "HttpErrorResponse", message: "Http failure response for http://localhost:3000/api/users: 500 Internal Server Error ", error: {…}} home.page.ts: 36: 14

In my NestJS backend I get this error message:

[Nest] 18696 - 03/27/2020, 10:39:04 AM [ExceptionsHandler] User validation failed: password: Path password is required., Username: Pathusername is required., Email: Path email is required. + 43794ms

In the network tab of the browser I get an error with the status code 500 (internal server error):

Request URL: http://localhost:3000/api/users
Request method: POST
Remote address: 127.0.0.1: 3000
Status code:
500
Version: HTTP / 1.1
Referrer Policy: no-referrer-when-downgrade

The required params are also sent correctly:

{"email":"[email protected]","username":"testname","password":"testpassword"}

The controller for my POST requests is structured like this:

@Controller('/users')
export class UsersController {
    constructor(private usersService: UsersService) { }

    // POST request containing the data required to create a new user
    @Post()
    async createUser(@Res() res, @Body() createUserDto: CreateUserDto) {
        console.log('body', createUserDto);

        const user = await this.usersService.create(createUserDto);
        if (!user) throw new InternalServerErrorException('User could not be created!');
        return res.status(HttpStatus.OK).json({
            message: "User has been created successfully",
            user
        })
    }
...

The DTO used looks like this:

export class CreateUserDto {
    readonly email: string;
    readonly username: string;
    readonly password: string;
}

CORS is also activated in my NestJS backend. In addition, it is funny that the GET requests (via Ionic as well as via Postman or direct input into the browser) work. POST requests also work if I make them via Postman or enter them directly into the browser.

I test the POST request in this way in my Ionic application:

  ngOnInit() {
    this.createAccount(this.createUserDto).subscribe((res) => {
      console.log('Request send', res);
    }, (err) => {
      console.log('Failed', err);

    });
  }

  createAccount(credentials): Observable<any> {
    return this.http.post('http://localhost:3000/api/users', JSON.stringify(credentials));
  }

It is also funny that the request is not sent when I remove JSON.stringify(credentials) and enter just credentials without JSON.stringify().

What am I doing wrong here?

4
  • Maybe the wrong httpclient.post overload is picked. Try to specify the content type as json directly and try to get it to work without JSON.stringify(). It should work without JSON.stringify()! this.http.post('http://localhost:3000/api/users', credentials, { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }) Commented Mar 27, 2020 at 10:56
  • Nope, still doesn't work. The body gets not passed to my backend and the request doesn't work without the JSON.stringify() method. The HttpClient is imported from '@angular/common/http'. I also added the headers like u suggested.. Commented Mar 27, 2020 at 11:08
  • How can the request not be send? Do you get a CORS error regarding preflight OPTIONS requests? Commented Mar 27, 2020 at 11:24
  • No, I'm just getting the errors listed in my questions. And if I log the body in my NestJS controller like console.log('body', createUserDto); it says: body CreateUserDto {}. And below the is the error a listed above. So my body sent to the controller is emplty, but in the browsers network tab the body is present. Also if I log it in my ionic app. Commented Mar 27, 2020 at 11:48

1 Answer 1

2

If your "credentials" is an object with the right interface then just send it as it is without JSON.stringify() it.

I assume that credencitial has something like this:

const credentials = {
    email: '[email protected]',
    username: 'username',
    password: 'some_password',
}

Then make a bit change into your observable to get the user data and catch properly the errors:

 createAccount(credentials): Observable<any> {
    return this.http.post('http://localhost:3000/api/users', credentials)
        .pipe(
           pluck('user'),
           catchError(err => {
            return throwError(err);
           })
        )
  }

Make sure to import the rxjs operators 'pluck' and 'catchError' and the observable 'throwError'.

For more information about these operators:

I hope it works to you! Good luck!

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the answer. The „credentials“ are an object using the right interface but if I use or send it without JSON.stringify() the request isn‘t sent to the backend. With JSON.stringify() the request lands in the backend. As I mentioned in my question: with Postman or by typing the endpoint url in the browser everything is working fine. And what exactly is „pluck“ doing here? Is it really needed?
When you make a request with http.post(URL, body) the body is being converted to a valid Json when it is sent to your backend, it is not necessary to convert to Json it does for you. Check more information [clicking here] (angular.io/guide/http#making-a-post-request). You are right the pluck is not necessary, is an optional operator that gets the user from the API response.
Okay but as I mentioned earlier. If I remove the stringify method the request is not send and nothing happens in the network tap of the browser dev tools.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.