'CORS is somehow stopping my Angular and Nestjs apps from communicating

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.



Solution 1:[1]

I realized from the error I was making a request to localhost:333 rather than localhost:3333 in the service file sending requests to the backend. That made the CORS error go away but I still have the other errors which I started a new question to address.

Solution 2:[2]

For the following, I just ran into this issue while working on an Angular 13 and Nest.js 8 app in an NX workspace.

For my part, I finally solved this CORS problem by adding the line app.enableCors(); in the main.ts file of the Nest.js application.

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    const globalPrefix = 'api';
    app.setGlobalPrefix(globalPrefix);
    app.enableCors();
    const port = process.env.PORT || 3000;
    await app.listen(port);
    Logger.log(
        `? Application is running on: http://localhost:${port}/${globalPrefix}`
    );
}

See the documentation:https://docs.nestjs.com/security/cors

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Optiq
Solution 2 jona303