Issue
I am building a little calculator app to learn Nest.js and Angular. I have set up a server hosting a simple web API with a few endpoints, one of which returns a list of all the currently supported Opcodes on the backend. I am trying to fetch (on init) and consume this list to populate a dropdown selector on the frontend.
Frontend
calculator-app/src/app/calculator-form/
holds the form component that consumes the request. All it is doing is calling OpcodeService.getSupportedOpcodes()
and logging the result. At this point, I know I'll need to do more work with the result object, but because of the CORS error I haven't gotten that far.
import { Component } from '@angular/core';
import { OpcodeService } from '../services/opcode.service';
@Component({
selector: 'app-calculator-form',
templateUrl: './calculator-form.component.html',
styleUrls: ['./calculator-form.component.scss'],
providers: [ OpcodeService ]
})
export class CalculatorFormComponent {
supportedOpcodes: string[] = ['?']
constructor(private opcodeService: OpcodeService) {}
ngOnInit() {
this.opcodeService.getListOfSupportedOpcodes().subscribe(res => {
console.log(res);
})
}
}
calculator-app/src/app/services/opcode.service.ts
makes the actual HTTP request. This endpoint works as expected when I test with Postman, and I did my best to emulate the header that worked with postman. This is also fairly simple, but its possible I'm missing some configuration here.
import { Injectable } from '@angular/core';
import { Enviornment } from '../enviornment';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
// declares that this service should be created
// by the root application injector.
providedIn: 'root'
})
export class OpcodeService {
supportedOpcodes: string[] = [];
constructor(private http: HttpClient) {}
getListOfSupportedOpcodes() {
const headers = new HttpHeaders()
.set('content-type', 'application/x-www-form-urlencoded')
.set('Access-Control-Allow-Origin', '*');
return this.http.get(Enviornment.serverUrl + "/opcode", {'headers': headers});
}
}
Backend
I'm reasonably confident there is nothing wrong with my routing. As mentioned above I was able to see the values returning as expected from GET -> localhost:3000/opcode. So here is my main.ts
file, with the enableCors()
configuration object.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
allowedHeaders: ['content-type'],
origin: 'http://localhost:4200/'
});
await app.listen(3000);
}
bootstrap().then(function() {
console.log("\nReady for maths!");
});
Screen capture of CORS error in Chrome
I have tried enabling CORS with the allowed headers. I know that Nest.js has issues parsing form-data
by default, so I tried setting the headers of the GET
request. Tried setting the origin following this post.
Here is the full repository. Feel free to open issues with any other feedback!
Solution
To access it from the front end locally you will have to change the main.ts enabled CORS settings.
From
app.enableCors({
allowedHeaders: ['content-type'],
origin: 'http://localhost:4200/'
});
To
app.enableCors(); //without any configuration option.
Main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(3000);
}
bootstrap().then(function() {
console.log("\nReady for maths!");
});
To handle it properly, we can keep this setting base on the environments settings to make this production usable code. The CORS setting can be kept in the application configuration on the hosting could service as well.
if (process.env.ENV === 'development' && process.env.LOCAL_ENV ===
'enabled') {
app.enableCors();
}
Working request from the angular app localhost: http://localhost:4200
Working request from the angular app local host
Answered By - Sandeep Yadav
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.