Introduction
I am undertaking a web application project the makes call to an API (Deezer). Deezer implements CORS restrictions which I got around easily enough with an Angular CLI Proxy. So locally my application works perfectly, but when I deploy to Firecase the API calls fail. The application has deployed perfectly, but fails when the user undertakes an action that triggers an API call.
Below is a screen shot of the error that presents on the console. The error is so weird (as you can see below), because it looks like the API was made with no issue as it returns a 200 OK status, but the "ok" field at the end of the object is false. So I don't think it is a CORS issues, but it may be - I don't know
My code
Below are the code extracts I think that would be relevant to be able to reproduce the error:
API service
/* eslint-disable linebreak-style */
/* eslint-disable max-len */
/* eslint-disable require-jsdoc */
/* eslint-disable new-cap */
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {
SearchedArtist,
ArtistDetails,
ArtistDetail}
from './deezer-api-interfaces';
@Injectable({
providedIn: 'root',
})
export class DeezerApiCallsService {
artistDetailPlaceHolder!: ArtistDetail
// eslint-disable-next-line no-invalid-this
artistDetails: ArtistDetails = {details: this.artistDetailPlaceHolder, top_tracks: [], albums: []}
listArtists: SearchedArtist[] = []
constructor(private http: HttpClient) { }
searchArtist(searchPhrase: String): SearchedArtist[] {
this.listArtists = [];
const query = '/search/artist?q="' + searchPhrase + '"';
this.deezerCalls(query).subscribe((result:any)=> {
for (let i = 0; i < result.data.length; i++) {
this.listArtists.push(result.data[i]);
}
});
return this.listArtists;
}
getArtistDetail(artistID: number) {
const query = '/artist/' + artistID;
this.deezerCalls(query).subscribe((result:ArtistDetail)=> {
this.artistDetails.details = result;
});
}
getArtistTopTracks(artistID: number) {
this.artistDetails.top_tracks = [];
const query = '/artist/' + artistID + '/top';
this.deezerCalls(query).subscribe((result:any)=> {
for (let i = 0; i < result.data.length; i++) {
this.artistDetails.top_tracks.push(result.data[i]);
}
});
}
getArtistAlbums(artistID: number) {
this.artistDetails.albums = [];
const query = '/artist/' + artistID + '/albums';
this.deezerCalls(query).subscribe((result:any)=> {
for (let i = 0; i < result.data.length; i++) {
this.artistDetails.albums.push(result.data[i]);
}
});
}
getArtistDetails(artistID: number): ArtistDetails {
this.getArtistDetail(artistID);
this.getArtistTopTracks(artistID);
this.getArtistAlbums(artistID);
return this.artistDetails;
}
deezerCalls(query: string): any {
return this.http.get<any>(query);
}
}
proxy.conf.js
/* eslint-disable linebreak-style */
const PROXY_CONFIG = [
{
context: [
'/search',
'/artist',
],
target: 'https://api.deezer.com',
secure: false,
logLevel: 'debug',
changeOrigin: true,
},
];
module.exports = PROXY_CONFIG;
package.json "scripts"
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.js",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"test-headless": "ng test --watch=false --browsers=ChromeHeadless"
},
angular.json "serve"
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "deezerplus:build",
"proxyConfig": "src/proxy.conf.js"
},
"configurations": {
"production": {
"browserTarget": "deezerplus:build:production"
},
"development": {
"browserTarget": "deezerplus:build:development"
}
},
"defaultConfiguration": "development"
},
firebase.json
{
"hosting": {
"public": "dist/deezerplus",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
Summary
One of my peers referred me to this follow link: https://stackoverflow.com/a/47534793/4331033 but I am not sure it the right solution and to be honest I am not 100% certain how to implement it.
If anyone can guide to how to overcome my problem I would be so grateful.