0

I'm upgrading my application from Angular 1.6 to Angular 6 and I'm stuck in the login screen. Below is a code snippet of what I am trying to do -

const body = new URLSearchParams();
body.set('username', 'admin')
body.set('password', 'admin');

this.http.post('/log-in',
  body,
  {
    headers: new HttpHeaders()
      .set('Content-Type', 'application/x-www-form-urlencoded')
  }
).subscribe((response: Response) => {
  // Do something here 
}

This is the error I get even though the response from the server is a 200 -

SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at XMLHttpRequest.onLoad (http.js:1514)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:3811)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:498)
at invokeTask (zone.js:1744)
at XMLHttpRequest.globalZoneAwareCallback (zone.js:1781)

Clearly, the response expected is a JSON but I am receiving a HTML page

{error: SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)   
at XMLHtt…, text: "<!DOCTYPE html>↵<html lang="en" layout ng-app="pfs…rc="scripts/index.js"></script>↵↵</body>↵</html>↵"}

I've searched a lot to figure out how to fix this but have made no progress so far. Tried the suggestions in

HttpClient POST request using x-www-form-urlencoded

How to force Angular2 to POST using x-www-form-urlencoded

But neither of it fixed the problem. I also tried changing the responseType of the httpOptions and still facing the same error.

This is the working AngularJS (1.6) code -

var postHeaders = {
  'Content-Type': 'application/x-www-form-urlencoded'
};    

$http({
      method: 'POST',
      url: '/log-in',
      data: $httpParamSerializerJQLike(
        {username: username, password: password}),
      headers: postHeaders,
    }).then(function (success) {
      // Do something
    }

Any help is greatly appreciated.

yazz
  • 301
  • 5
  • 15

2 Answers2

1

Most likely this is because what you are posting to your back-end is incorrectly formatted so it's throwing an error and returning a HTML page. You shouldn't be sending a URLSearchParams object as your body, you should send a regular object:

const body = {
    username: 'admin',
    password: 'admin',
};
Simon K
  • 2,762
  • 1
  • 11
  • 20
  • I tried the above suggested along with the other two suggestions from the stackoverflow answers in the links I have added to my question - one of it is what you see in my question. None of it worked. But I found what I needed to do to make it work. I'll post it below as an answer. Thanks for you suggestion. – yazz Feb 26 '19 at 17:19
0

I was able to make this work after I did this - I had to add the following responseType to my options

return this.http.post('http://localhost/api/v1/log-in',
  body, { responseType: 'text' as 'json' }
)

Previously when I added responseType as 'text' I kept getting an error about a type mismatch. The key for me was to set it as 'text' as 'json'.

yazz
  • 301
  • 5
  • 15