3

I recently started learning Angular (4) and followed the tutorials of Angular.io.

But now that I'm trying to build my own application I'm running into a bit of a problem. I've spent the whole day trying to figuring this out but I failed.

I'm working on an auth service that has only a login and a logout for now.

The login works fine, but I don't get the logout to work. It seems to break on the toPromise() call.

const url = `${environment.serviceURL}/api/account/logout`;
const headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded',
    'withCredentials':true,
    'Authorization': `Bearer ${this.token}`});
let options = new RequestOptions({headers: headers});
let result = this.http.post(
     url, options).toPromise().then(/*do something*/);

This gives me the following error in the console:

ERROR Error: Uncaught (in promise): TypeError: v.split is not a function
TypeError: v.split is not a function at http://localhost:4200/vendor.bundle.js:26382:76
at Array.forEach (native)
at http://localhost:4200/vendor.bundle.js:26382:20
at Map.forEach (native)
at Headers.toJSON (http://localhost:4200/vendor.bundle.js:26380:23)
at Object.stringify (<anonymous>)
at Request.Body.text (http://localhost:4200/vendor.bundle.js:26957:25)
at Request.getBody (http://localhost:4200/vendor.bundle.js:27865:29)
at Observable._subscribe (http://localhost:4200/vendor.bundle.js:27393:37)
at Observable._trySubscribe (http://localhost:4200/vendor.bundle.js:567:25)
at http://localhost:4200/vendor.bundle.js:26382:76
at Array.forEach (native)
at http://localhost:4200/vendor.bundle.js:26382:20
at Map.forEach (native)
at Headers.toJSON (http://localhost:4200/vendor.bundle.js:26380:23)
at Object.stringify (<anonymous>)
at Request.Body.text (http://localhost:4200/vendor.bundle.js:26957:25)
at Request.getBody (http://localhost:4200/vendor.bundle.js:27865:29)
at Observable._subscribe (http://localhost:4200/vendor.bundle.js:27393:37)
at Observable._trySubscribe (http://localhost:4200/vendor.bundle.js:567:25)
at resolvePromise (http://localhost:4200/polyfills.bundle.js:3224:31)
at http://localhost:4200/polyfills.bundle.js:3150:17
at SafeSubscriber._error (http://localhost:4200/vendor.bundle.js:66387:85)
at SafeSubscriber.__tryOrSetError (http://localhost:4200/vendor.bundle.js:16367:16)
at SafeSubscriber.error (http://localhost:4200/vendor.bundle.js:16321:26)
at Subscriber._error (http://localhost:4200/vendor.bundle.js:16248:26)
at Subscriber.error (http://localhost:4200/vendor.bundle.js:16222:18)
at Observable._trySubscribe (http://localhost:4200/vendor.bundle.js:572:18)
at Observable.subscribe (http://localhost:4200/vendor.bundle.js:555:27)
at http://localhost:4200/vendor.bundle.js:66387:15

The mayor difference is (at least I think) that the login returns data containing the user info and the logout doesn't return any data. It just removes the session in the service.

I just want to know if the request has succeeded so I can act upon it. What am I doing wrong or what should I do differently to get this working?

SEG.Veenstra
  • 718
  • 1
  • 7
  • 18
  • I'd recommend that you don't use promises and use observables instead. I have a complete CRUD example app here: https://github.com/DeborahK/Angular2-ReactiveForms – DeborahK Jun 24 '17 at 19:35
  • Do you use split function on your data when you call login url? If so, I assume you use the same function for logout which calls the same promise function. You should use different http calls for each. – Bunyamin Coskuner Jun 24 '17 at 19:36
  • @DeborahK I will check it out. Can you elaborate on why observables are 'better'? – SEG.Veenstra Jun 24 '17 at 20:09
  • @BunyaminCoskuner both are two separate functions and API endpoints. I'm also not splitting anything myself. I think the toPromise is trying to do that somehow. – SEG.Veenstra Jun 24 '17 at 20:11
  • @SEG.Veenstra do you run your app in prod mode? If so, can you remove --prod tag which may give more detailed error. – Bunyamin Coskuner Jun 24 '17 at 20:15
  • @BunyaminCoskuner I'm running it in Dev mode. What I've posted is all the error I'm getting. – SEG.Veenstra Jun 24 '17 at 20:30
  • Can you confirm that it's the `let result =` line that is throwing the error and not one of the lines above it? In browser dev tools, if you open the network monitor tool, is an HTTP call actually made? – BeetleJuice Jun 24 '17 at 20:40
  • @SEG.Veenstra I don't think toPromise is causing that. There is no .split call in toPromise if I'm not mistaken. Check here --> https://github.com/ReactiveX/rxjs/blob/88ec8dc54b6ede043f779232e33e3939b870e3dc/src/operator/toPromise.ts Can you try to find who is calling .split function? – Bunyamin Coskuner Jun 24 '17 at 20:40
  • @BeetleJuice If I remove the `toPromise()` I'm not getting an error. But both times no HTTP call is made. Any idea why? – SEG.Veenstra Jun 24 '17 at 21:07
  • Guys, I found an error on my behalve. I had to put in `null` for the body param to at least let the HTTP request work. It probable tried to parse the options as the body or something... oops. I'm now facing some CORS errors, but that's an other matter. THX guys! – SEG.Veenstra Jun 24 '17 at 21:13
  • 1
    To answer your question to me ... see this post on Promises vs Observables: https://stackoverflow.com/questions/37364973/angular-promise-vs-observable – DeborahK Jun 24 '17 at 21:22
  • 1
    @SEG.Veenstra good catch on null input. About your other question, http returns an Observable which is by default lazy. If you don't subscribe to an Observable, it won't execute. In this case, it won't make the http call. You should either subscribe to it or you can use async pipe in your html which also does the same thing. – Bunyamin Coskuner Jun 24 '17 at 21:37

1 Answers1

2

This had nothing to do with the toPromise() as @Bunyamin Coskuner and @BeetleJuice pointed out in the comments. I found out that I made a mistake in calling the http.post methode without the body parameter which caused the function to take the options as the body.

changing:

let result = this.http.post(
 url, options).toPromise().then(/*do something*/);

to:

let result = this.http.post(
 url, null, options).toPromise().then(/*do something*/);

Solved my error!

SEG.Veenstra
  • 718
  • 1
  • 7
  • 18