6

I am using Angular2 RC5 (core, http, etc) and trying to connect to a CORS enabled Node.js server. My application is fresh generated from Angular-CLI (version: "1.0.0-beta.11-webpack.2").

// src/app/app.component.ts
...
ngOnInit () {
   const headers: Headers = new Headers();
   headers.append('Accept', 'application/json');
   headers.append('Content-Type', 'application/json');
   headers.append('Access-Control-Allow-Origin', '*');

   const options = new RequestOptions({
     headers: headers
   });

   this.http.get('http://localhost:9000/api/v1/users', options)
    .map((res: Response) => res.json())
    .subscribe(users => console.log(users));
}

...

When the application starts, the OnInit hook got called, I got an error in the console. Here is the error message that I got.

EXCEPTION: TypeError: Cannot read property 'toString' of null
browser_adapter.js:84EXCEPTION: TypeError: Cannot read property 'toString' of nullBrowserDomAdapter.logError @ browser_adapter.js:84BrowserDomAdapter.logGroup @ browser_adapter.js:94ExceptionHandler.call @ exception_handler.js:65(anonymous function) @ application_ref.js:267ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.js:53ZoneDelegate.invoke @ zone.js:322Zone.run @      zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.js:44ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474
zone.js:461 Unhandled Promise rejection: Cannot read property 'toString' of null ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read property 'toString' of null(…)consoleError @ zone.js:461_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494
zone.js:463 Error: Uncaught (in promise): TypeError: Cannot read property 'toString' of null(…)

If I drop off the options and header completely, I got CORS error but response status 200 from the server. (I guess that If I can pass the correct Header, it should work. )

 this.http.get('http://localhost:9000/api/v1/users')
  .map((res: Response) => res.json())
  .subscribe(users => console.log(users)); 

Here is the error from the console

XMLHttpRequest cannot load http://localhost:4000/api/v1/users. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
browser_adapter.js:93EXCEPTION: Response with status: 0  for URL: null
browser_adapter.js:84EXCEPTION: Response with status: 0  for URL: nullBrowserDomAdapter.logError @         browser_adapter.js:84BrowserDomAdapter.logGroup @    browser_adapter.js:94ExceptionHandler.call @ exception_handler.js:65next @ application_ref.js:348schedulerFn @ async.js:89SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @     Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:77onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runTask @ zone.js:259ZoneTask.invoke @ zone.js:423
Subscriber.js:229Uncaught Response with status: 0  for URL: null

Can someone help, please? thanks.

3 Answers 3

4

I am a newbie so bear with me please, but as far as I am concerned the Access-Control-Allow-Origin header should be returned by the backend Node.js server. CORS on server side is disabled by default due to security. Use the following question to help you with implementation: How to allow CORS?

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

4 Comments

Thank you for commenting. My server is enabled CORS and should be able to return the payload. Here is more generic question, if I simply want to pass custom header value via Angular2 HTTP, how can I do that? I did it in the beta version of Angular2. Now in RC5, does @angular/http change its calling signature?
In that case I am scared that I won't be able to help you. Your code seems perfectly legitimate to me. I will try to reproduce the problem tomorrow.
Still, I suggest you check that there is 'Access-Control-Allow-Origin' header present on the response from the server given that the second error suggests otherwise. Also please note that 'Access-Control-Allow-Origin' header is response header and there is no reason to put it on the request.
Mike, You are right on 'Access-Control-Allow-Origin' header present on the response. The issue is not from angular2 code. It is the server side problem. I am not using Express, instead of a brand new framework called egg.js. So many things that I am still trying to figure out. Well, I finally nailed down the issue and fixed on the server side.
1

Your problem is caused by a bug introduced in rc5. The XHRBackend for Http was modified to convert the body of any request into a string. It looks at the Content-Type header and attempts to call the appropriate conversion method.

In your code above, you are setting the Content-Type header to application/json which causes the XHRBackend to try to convert it into a string. However, since you're making a GET request, body is null, so this exception is being thrown.

In your case, just remove the Content-Type header, and everything should work fine.

Comments

1

It is written about here:

https://github.com/angular/angular/issues/10612

To resolve

EXCEPTION: TypeError: Cannot read property 'toString' of null

you need to set body to ''

headers.append('body', '');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.