I'm building an app with Angular and NestJS using NGXS for state management. I got everything set up and served my application and got this error in the console.
Access to XMLHttpRequest at 'localhost:333/api/product-index' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
After doing a little research I found this article explaining how to handle CORS in our Angular apps and after checking the files it tells us to modify I saw that the settings were already present. I was confused about the server.js
file it told us to update and after looking into what's typically done in a server.js
file I came to the conclusion that in Angular it must be the main.ts
file however I don't know if I need to make the modifications to the main.ts
file in my Nest app or the one in my Angular app. I'm using a nrwl nx
monorepo for my apps as well.
This is the proxy.conf.json
file from my angular app
{
"/cre8or-maker-backend": {
"target": "http://localhost:3333",
"secure": false,
"logLevel": "debug"
}
}
This is the serve
object of the architect
object in my angular.json
file.
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "cre8or-maker:build",
"proxyConfig": "apps/cre8or-maker/proxy.conf.json"
}
As I said before these settings were already present in these files and the only thing that seems new to me is the part about modifying the server.js
file which I'm assuming is the main.ts
file in Angular world. Here's what my main.ts
files look like
nest main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const globalPrefix = 'api';
app.setGlobalPrefix(globalPrefix);
const port = process.env.port || 3333;
await app.listen(port, () => {
console.log('Listening at http://localhost:' + port + '/' + globalPrefix);
});
}
bootstrap();
angular main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.error(err));
I installed the cors
npm package already, I just don't know what else I'm suppose to do to get this working, can anyone help?
UPDATE
I tried adding app.enableCors();
to the main.ts
file in my NestJs app as well as modifying the create(AppModule)
function to be create(AppModule, {cors: true})
and neither solve the problem. I also added the following snippet of code which didn't help either.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
next();
});
As of right now I only have one state defined making an API request to the back end. Inside my state I have an action which looks like this
@Action(GetProductIndexList)
getProductIndexListData({patchState, dispatch, getState}: StateContext<ProductIndexListModel>){
return this.dataService.fetchProductIndexList().pipe(tap((result)=>{
const state = getState();
patchState({items:[...state.items, ...result]});
}));
}
I make the api call inside of a service file which I'm calling dataService
in the state's constructor. The service file looks like this.
@Injectable({ providedIn: 'root' })
export class ProductIndexService{
constructor(private httpClient: HttpClient){}
private readonly URL: string = 'localhost:3333/api';
public fetchProductIndexList():Observable<CattegoryIndexItem[]>{
const path: string = this.URL + '/product-index';
return this.httpClient.get(path) as Observable<CattegoryIndexItem[]>;
}
}
In NestJS I can successfully call the data without any errors so I know the controllers are set up properly but if anybody wants to see how I have things set up there let me know and I'll update this question with the code.
private readonly URL: string = 'https://localhost:3333/api';
– Diaphysiscore.js:6185 ERROR HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "https://localhost:3333/api/product-index", ok: false, …}
andGET https://localhost:3333/api/product-index net::ERR_CONNECTION_REFUSED
– Kraken