How to make a simple JSONP asynchronous request in Angular 2?
Solution 1
In the latest version of Angular
-
Import HttpClientModule and HttpClientJsonpModule modules in your app module's definition file
import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http'; @NgModule({ declarations: [ //... List of components that you need. ], imports: [ HttpClientModule, HttpClientJsonpModule, //... ], providers: [ //... ], bootstrap: [AppComponent] })
-
Inject http and map rxjs operator into your service:
import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/http'; import 'rxjs/add/operator/map'; @Injectable() export class MegaSuperService { constructor(private _http: HttpClient) {} }
-
Make JSONP requests in the following way:
// inside your service this._http.jsonp('/api/get', 'callback').map(data => { // Do stuff. });
In Angular version 2 - version 4.3
-
Import JSONP module in your app module's definition file:
import {JsonpModule} from '@angular/http'; @NgModule({ declarations: [ //... List of components that you need. ], imports: [ JsonpModule, //... ], providers: [ //... ], bootstrap: [AppComponent] })
-
Inject jsonp service and map rxjs operator into your service:
import {Injectable} from '@angular/core'; import {Jsonp} from '@angular/http'; import 'rxjs/add/operator/map'; @Injectable() export class MegaSuperService { constructor(private _jsonp: Jsonp) {} }
-
Make requests using "JSONP_CALLBACK" as a callback property:
// inside your service this._jsonp.get('/api/get?callback=JSONP_CALLBACK').map(data => { // Do stuff. });
Solution 2
In Angular 4.3 and up you should use HttpClientModule because the JsonpModule is deprecated.
- Import HttpClientModule and HttpClientJsonpModule into your module.
- Inject HttpClient into your service.
- Pass the callback key as the second argument for the
jsonp
method.
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// Import relevant http modules
import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { ExampleService } from './example.service';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
// Import relevant http modules
HttpClientModule,
HttpClientJsonpModule
],
providers: [ExampleService],
bootstrap: [AppComponent]
})
export class AppModule { }
example.service.ts
import { Injectable } from '@angular/core';
// Import HttpClient class
import { HttpClient } from '@angular/common/http';
@Injectable()
export class ExampleService {
// Inject HttpClient class
constructor(private http: HttpClient) { }
getData() {
const url = "https://archive.org/index.php?output=json&callback=archive";
// Pass the key for your callback (in this case 'callback')
// as the second argument to the jsonp method
return this.http.jsonp(url, 'callback');
}
}
Solution 3
If this endpoint is jsonp-compliant, you can use the following. You need to find out the parameter to use to provide the jsonp callback. In the code below, I call it c
.
After having registered JSONP_PROVIDERS
when calling the bootstrap
function:
import {bootstrap} from 'angular2/platform/browser'
import {JSONP_PROVIDERS} from 'angular2/http'
import {AppComponent} from './app.component'
bootstrap(AppComponent, [ JSONP_PROVIDERS ]);
You can then execute your request using an instance of the Jsonp
class you injected from constructor:
import {Component} from 'angular2/core';
import {Jsonp} from 'angular2/http';
@Component({
selector: 'my-app',
template: `
<div>
Result: {{result | json}}
</div>
`
})
export class AppComponent {
constructor(jsonp:Jsonp) {
var url = 'https://accounts.google.com/logout&c=JSONP_CALLBACK';
jsonp.request(url, { method: 'Get' })
.subscribe((res) => {
(...)
});
}
}
See this question for more details:
nunoarruda
Result-Oriented Front End Angular Engineer with a strong technical skill-set, attention to detail, and 17 years of experience. I have a passion for translating beautiful designs into functional user interfaces and building great web applications. I actively seek out new technologies and stay up-to-date on industry trends and advancements. Continued education has allowed me to stay ahead of the curve and deliver exceptional work to each employer I’ve worked for. I've successfully delivered projects like a CSS UI library used by 17,000 employees, a mobile app that has 120,000+ users, and a web app serving over 100 million images. I've done frontend work for Adobe, Webflow, Bayer, among other companies. I'm originally from Portugal but I've been working remotely for the last 6 years for companies worldwide. I can be flexible in order to have overlapping working hours with a distributed team.
Updated on February 27, 2021Comments
-
nunoarruda about 3 years
I'm trying to convert the following Angular 1 code to Angular 2:
$http.jsonp('https://accounts.google.com/logout');
It needs to be a JSONP request to skip the CORS policy issue.
-
MoshMage over 7 yearsany idea why this "exact same code" can throw a
EXCEPTION: Response with status: 200 Ok for URL: null
, never entering in themap
function ? -
Gaston K over 7 yearsI'm getting the follow error: Uncaught ReferenceError: __ng_jsonp____req0_finished is not defined and JSONP injected script did not invoke callback. Any idea? My api call has the jsonp parameter. api.instagram.com/v1/users/self/…{myAccesToken} I'm importing jsonp from angular/http and injecting in into the constructor. Also I added to the imports in the app.module.ts file.
-
nebulae about 7 years@MoshMage are you seeing that behavior in both IE & Chrome? Chrome is working fine for me, IE is throwing an error behind the scenes yet returning a response 200: OK to the subscription.
-
nebulae about 7 years@GastonK is the API expecting the callback to be "JSONP_CALLBACK"? angular overwrites this with the __ng_jsonp____req<count>_finished if it sees this exact string. see: github.com/angular/angular/blob/…
-
Rahul Upadhyay over 6 yearsThank you. Just an addition to this answer, we need to replace 'callback' with 'JSONP_CALLBACK'.
-
Courtney Pattison over 6 years@RahulUpadhyay I've updated the answer with your correction. Thank you!
-
kcrisman over 6 yearsAs a data point, I found that not only was
&callback=JSONP_CALLBACK
unnecessary, it broke things - but perhaps that was in a different/newer/older version of Angular; anyway, it just "knew" to add and then remove the callback info for some reason. YMMV. -
Courtney Pattison about 6 years@kcrisman Good catch! Looking at line 1124 of the HttpClient
JSONP_CALLBACK
is appended to the callback parameter. I'll update my answer now. -
alex351 over 3 yearsNow there is a new issue. Cross-Origin Read Blocking (CORB) blocked cross-origin response
-
workaholic almost 3 yearsThis has changed little over time. However, 3rd-parties may have their own name for the callback parameter, that second argument to http.jsonp. I have seen 'callback' or 'c' most commonly. And so in the url in this answer,
&callback=archive
doesn't need to exist. Angular will add that parameter you name to the passed url, such as&callback=ng_jsonp_callback_0
. The actual callback function should be the success function of the http.jsonp Observable. This extra bit helped me to deal with Pardot form submissions.