JSONP is one way to get around CORS when getting data from a REST service. It does require a callback feature on the part of the service, which isn’t readily clear in some of the blogs and samples online for JSONP. With or without JSONP, the server side has the ability to disable CORS. This could be useful if a service you want to call, and cannot modify, supports JSONP.
If you are adding support for it in your rest, you’ll be checking for a callback parameter, which we’ll make “callback” in this example. If your REST is in Java, you’d include this parameter:
@QueryParam("callback") String callback
Then your output might look like this:
if (callback != null) {
out.append(callback).append("(");
}
out.append(data);
if (callback != null) {
out.append(");");
}
In your component’s module, you’ll need to add this to your @NgModule imports:
HttpClientModule,
HttpClientJsonpModule,
imported with
import { HttpClientJsonpModule, HttpClientModule } from '@angular/common/http';
The odd thing I discovered was that you need HttpClientModule in your component’s module even if it is already declared in your application module. This isn’t very logical because the HttpClient worked just fine in my components with this only being in app.module.ts. But, when I tried to use JSONP, I kept getting this error in the JavaScript console:
Error: “Attempted to construct Jsonp request without JsonpClientModule installed.”
Yeah, I’m writing this blog to hopefully save another poor soul the torture of trying to connect those dots. I couldn’t find that error anywhere on the Internet; and, with HttpClient working just fine in the same component without JSONP, why do you need HttpClientModule in your submodule just for JSONP?
In your Angular service or component, you’ll then be able to use JSONP to call your service:
this.http.jsonp(url, 'callback')
.pipe(
catchError(this.handleError('jsonpTest', 'ERROR')),
).subscribe(data => {
this.log('data: ' + JSON.stringify(data));
});
That second parameter in your jsonp call is the name of the parameter it will pass to the back-end. The value of that parameter passed to your service will be defined by JSONP.