Search code examples
javascriptangulartypescriptjsonp

Getting JSON data using JSONP from Flickr api


I'm facing a new issue - Jsonp. I've read about and watched videos but couldn't get to the solution to fix my problem.

First I'm using Angular 6. I'm trying to get a json response from an api which uses JSONP, but when I try to use it in my app I got CORS error. So I want to fix it without having to install chrome's CORS plugin. The response on the browser is like this:

jsonFlickrFeed({
  "title": "Uploads from everyone",
  "link": "https:\/\/www.flickr.com\/photos\/",
  "description": "",
  "modified": "2018-10-13T21:16:50Z",
  "generator": "https:\/\/www.flickr.com",
  "items": [{
      "title": "photo 2504 was taken at 14:18:38",
      "link": "https:\/\/www.flickr.com\/photos\/barrycorneliusox\/30359327537\/",
      "media": {
        "m": "https:\/\/farm2.staticflickr.com\/1944\/30359327537_fac974807d_m.jpg"
      },
      "date_taken": "2018-10-13T14:18:38-08:00",
      "description": " <p><a href=\"https:\/\/www.flickr.com\/people\/barrycorneliusox\/\">barrycorneliusox<\/a> posted a photo:<\/p> <p><a href=\"https:\/\/www.flickr.com\/photos\/barrycorneliusox\/30359327537\/\" title=\"photo 2504 was taken at 14:18:38\"><img src=\"https:\/\/farm2.staticflickr.com\/1944\/30359327537_fac974807d_m.jpg\" width=\"240\" height=\"160\" alt=\"photo 2504 was taken at 14:18:38\" \/><\/a><\/p> <p><a href=\"http:\/\/www.oxonraces.com\/photos\/2018-10-13-oxford\/\" rel=\"nofollow\">Click here for more photos of the 2018 Chiltern XC League Match 1 - Oxford<\/a>. If you put a photo somewhere public, please add the credit <em>Photo by Barry Cornelius<\/em>.<\/p>",
      "published": "2018-10-13T21:16:50Z",
      "author": "[email protected] (\"barrycorneliusox\")",
      "author_id": "159968055@N03",
      "tags": "2018 chilternxcleaguematch1oxford oxford jsvmenpointjfirstlap barrycornelius oxonraces"
    },
    .....,
  ]

})

my service:(using jsonp)

getImages() {
  return this.jsonp.request(this.imagesUrl).subscribe(res => {
    console.log(res);
  })
}

doesn't work. what am I doing wrong?

my api URL :

https://api.flickr.com/services/feeds/photos_public.gne?format=json


Solution

  • Since you're using Angular 6,

    You'll have to import HttpClientModule, HttpClientJsonpModule and add them to your imports array of your Module that you want to make this call in:

    ...
    import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http';
    ...
    
    @NgModule({
      imports: [..., HttpClientJsonpModule, HttpClientModule, ...],
      ...
    })
    export class AppModule { }
    

    Then in your service, in the API URL, you'll also have to specify jsoncallback=JSONP_CALLBACK instead of nojsoncallback=callback:

    import { Injectable } from '@angular/core';
    
    import { HttpClient } from '@angular/common/http';
    
    @Injectable()
    export class PhotoService {
    
      imagesUrl = `https://api.flickr.com/services/feeds/photos_public.gne?format=json&jsoncallback=JSONP_CALLBACK`;
    
      constructor(private http: HttpClient) { }
    
      getImages() {
        return  this.http.jsonp(this.imagesUrl, 'JSONP_CALLBACK');
      }
    
    }
    

    And then in your Component:

    ...
    
    import { PhotoService } from './photo.service';
    
    ...
    export class PhotosComponent  {
    
      myArray: any[];
    
      constructor(private photoService: PhotoService) { 
      }
    
      ngOnInit() {
        this.photoService.getImages()
          .subscribe((res: any) => this.myArray = res.items);
      }
    
    }
    

    Here's a Sample StackBlitz for your ref.

    PS: You're also subscribeing inside getImages which would return a Subscription instead of an Observable