Failed to load resource: the server responded with a status of 404 (Not Found) Angular12 Spring boot - spring

I am new to Sping Boot, rest api and angular12,
I am running my program in vscode to call the back api and i get the error "Failed to load resource: the server responded with a status of 404 (Not Found)"
my codes:
backend controller :
#RestController
#RequestMapping("/evaluationController/")
public class EvaluationController {
#Autowired
private EvaluationRepository evaluationrepository;
//get all evaluationsnotes
#CrossOrigin(origins = "http://localhost:4200/")
#GetMapping("/notes")
public List<EvaluationModel> getAllEvaluations(){
return evaluationrepository.findAll();
}
//post notes
#PostMapping("/notes")
public EvaluationModel createEvaluationNote(#RequestBody EvaluationModel evaluationNote) {
return evaluationrepository.save(evaluationNote);
}
}
My front end angular12 service
#Injectable({
providedIn: 'root'
})
export class EvaluationserviceService {
private baseUrl!: "http://localhost:8080/evaluationController/notes";
constructor(private httpClient: HttpClient) { }
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
}
getEvaluationNotes():Observable<Evaluationotes[]>{
return this.httpClient.get<Evaluationotes[]>(`${this.baseUrl}`);
}
}
my typescript file
#Component({
selector: 'app-fin-evaluation',
templateUrl: './fin-evaluation.component.html',
styleUrls: ['./fin-evaluation.component.css']
})
export class FinEvaluationComponent implements OnInit {
evaluationNote!: Evaluationotes[];
constructor(private evaluationNoteService: EvaluationserviceService ) { }
ngOnInit(): void {
this.getAllNotes();
}
private getAllNotes(){
this.evaluationNoteService.getEvaluationNotes().subscribe(data=>{
this.evaluationNote = data;
});
}
}
Thank you!

The issue is with the baseUrl, you need to use = (used for initialization) instead of : (used in typescript to define an objects type). Since you are never really initializing the variable with proper url, request is going to some random url like http://localhost:4200/undefined causing 404. You can update the url as follows and try:
private baseUrl = "http://localhost:8080/evaluationController/notes";

Related

NestJS Dependency Injection in Websocket Adapter

I'm trying to authenticate and check permission of a user while establishing a websocket connection in a NestJS application.
I've found this discussion which recommends to make use of NestJS Websocket adapter. You can perform the token validation in the options.allowRequest callback as below.
export class AuthenticatedSocketIoAdapter extends IoAdapter {
private readonly authService: AuthService;
constructor(private app: INestApplicationContext) {
super(app);
this.authService = app.get(AuthService);
}
createIOServer(port: number, options?: SocketIO.ServerOptions): any {
options.allowRequest = async (request, allowFunction) => {
const token = request.headers.authorization.replace('Bearer ', '');
const verified = this.authService.verifyToken(token);
if (verified) {
return allowFunction(null, true);
}
return allowFunction('Unauthorized', false);
};
return super.createIOServer(port, options);
}
}
I have a problem however with the dependency injection in the websocket adapter. The IoAdapter's constructor has an INestApplicationContext parameter from which I'm trying to get back the AuthService using app.get(AuthService) as you can see above.
The AuthService injects two other services, a UserService and the JwtService to check the JWT token. My problem is that those services remained not defined in that context.
#Injectable()
export class AuthService {
constructor(private usersService: UsersService, private jwtService: JwtService) {}
verifyToken(token: string): boolean {
// Problem: this.jwtService is undefined
const user = this.jwtService.verify(token, { publicKey });
// ... check user has permissions and return result
}
For info, the AuthService is in another module than the one which defines the Websocket. I also tried to import the AuthService (and its dependencies) in the current module but that didn't help.
Is that possible to make use the service using the app.get() method?
I could solve the DI issue by using app.resolve() instead of app.get()
export class AuthenticatedSocketIoAdapter extends IoAdapter {
private authService: AuthService;
constructor(private app: INestApplicationContext) {
super(app);
app.resolve<AuthService>(AuthService).then((authService) => {
this.authService = authService;
});
}
}
This solved the jwtService injected in the AuthService being undefined.

WebTestClient gets 404 on Spring Boot 2.4.0-M3 while works fine on 2.4.0-M2

I have test that works properly with Spring 2.4.0-M2 but after upgrading to 2.4.0-M3 it breaks - returns 404 for a route that is registered.
My app:
#SpringBootApplication(proxyBeanMethods = false)
class ExampleApp
fun main(args: Array<String>) {
runApplication<ExampleApp>(
init = {
addInitializers(BeansInitializer())
},
args = args
)
}
beans:
class BeansInitializer : ApplicationContextInitializer<GenericApplicationContext> {
#Suppress("LongMethod")
override fun initialize(applicationContext: GenericApplicationContext) {
beans {
bean {
router {
"/routes".nest {
GET("/{id}") { ServerResponse.ok().bodyValue(Foo("ok")) }
POST("/") { ServerResponse.ok().bodyValue(Foo("ok")) }
}
}
}
}
.initialize(applicationContext)
}
}
data class Foo(val status: String)
My test:
#SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = [
ExampleApp::class
]
)
class FailingTest #Autowired constructor(
context: ApplicationContext,
) {
val webTestClient: WebTestClient = WebTestClient.bindToApplicationContext(context)
.configureClient()
.build()
#Test
fun `should interact with routes`() {
webTestClient
.post()
.uri("/routes")
.bodyValue(SampleBody("123"))
.exchange()
.expectStatus()
.isOk // returns 404 on 2.4.0-M3 / passes on 2.4.0-M2
}
data class SampleBody(val id: String)
}
test application.yml
context:
initializer:
classes: com.example.BeansInitializer
On 2.4.0-M3 tests fail with following message:
java.lang.AssertionError: Status expected:<200 OK> but was:<404 NOT_FOUND>
On 2.4.0-M2 they pass.
Is there something that changed through the versions? Or this is a bug?
The change in behaviour that you are seeing is due to an improvement in Spring Framework during the development of 5.3.
By default, Spring Framework will match an optional trailing path separator (/). This optional / should be in addition to the path specified in your routes.
You have two routes:
GET /routes/{id}
POST /routes/
The support for an optional trailing path separator means that you could make a get request to /routes/56/ (an additional trailing /), but it should not mean that you can make a request to POST /routes (removal of a trailing /).
If you want to be able to make POST requests to both /routes and /routes/, you should define the route as /routes:
beans {
bean {
router {
"/routes".nest {
GET("/{id}") { ServerResponse.ok().bodyValue(Foo("ok")) }
POST("") { ServerResponse.ok().bodyValue(Foo("ok")) }
}
}
}
}

GET request to API request give status code of 502. How can I resolve this?

I am building an application with nestjs framework. I have created controller and service to fetch data from Http endpoint. Instead of getting the json data I am getting
Error: Request failed with status code 502
at createError (node_modules/axios/lib/core/createError.js:16:15)
at settle (node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (node_modules/axios/lib/adapters/http.js:237:11)
at IncomingMessage.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19) in the output. The endpoint is working fine on Google Chrome. I have integrated my application with Swagger UI. What changes should I make in my code so that I can get data from endpoint?
Here is my service.ts
import { Injectable, HttpService } from '#nestjs/common';
import { map } from 'rxjs/operators';
#Injectable()
export class MessageService {
constructor(private readonly httpService: HttpService) {}
configEndPoint: string = 'https://jsonplaceholder.typicode.com/todos/1';
getData(source: string, productCode: string, vehicleType: string) {
return this.httpService
.get(this.configEndPoint)
.pipe(map(response => response.data.json()));
}
}
Here is my controller.ts
import { Controller, Post, Body, Get } from '#nestjs/common';
import {
ApiImplicitHeader,
ApiOperation,
ApiResponse,
ApiUseTags,
} from '#nestjs/swagger';
import { ProductEvent } from '../dto/product-event';
import { MessageService } from '../service/message/message-service';
#Controller('/service/api/message')
export class MessageController {
source: string;
productCode: string;
vehicleType: string;
constructor(private messageService: MessageService) {}
#Post()
#ApiUseTags('processor-dispatcher')
#ApiOperation({ title: 'Generate product message for the SNS topics' })
async generateMessage(#Body() productEvent: ProductEvent) {
return JSON.stringify(
this.messageService.getData(
this.source,
this.productCode,
this.vehicleType,
),
);
}
}

Inner Error: Message: controllerFactory.createForCurrentScope is not a function

I am recieving the above error in the aurelia view model
Inner Error: Message: controllerFactory.createForCurrentScope is not a
function
Here is the code,
export class UpdateClient {
public httpClient: HttpClient;
public router: Router;
public clientHelper: ClientHelper;
public validator: Validator;
public canSave: boolean;
public controller: ValidationController;
public client: Client ;
constructor(httpClient: HttpClient, router: Router, clientValidator: ClientValidator, clientHelper: ClientHelper, controllerFactory: ValidationControllerFactory, validator: Validator) {
this.httpClient = httpClient;
this.clientHelper = clientHelper;
this.router = router;
this.client = new Client
this.controller = controllerFactory.createForCurrentScope(validator);
clientValidator.validate(this.client, clientHelper);
}
You need to have #autoinject() or any other decorator on your UpdateClient class for the type metadata to be emitted correctly.
ValidationControllerFactory is registered with DI as a resolver in the module file, so simply importing that (which you have, otherwise you'd get a type error) should give you the correct thing.
You may need to double check that you have experimentalDecorators and emitDecoratorMetadata set to true in your tsconfig.json.
Also make sure you are registering the validation plugin in your main.ts like so:
aurelia.use.plugin(PLATFORM.moduleName('aurelia-validation'))

HttpClient Angular 5 does not send request

I have a problem with HttpClient in Angular 5. HttpClient does not send any request (I don't see any xhr log in console) on two specified components. On the others components everything is fine.
Calling ApiService POST method (custom service which works like a wrapper for HttpClient) from Component A, but when I call this method from Component B
HttpClient seems to be frozen.
There are many components in my app that use ApiService. Everything is injected fine. I have no idea what is wrong.
--- respond
ApiService.ts
#Injectable()
export class ApiService
{
private errorListeners : Map<string, Array<(details ?: any) => any>> =
new Map<string, Array<(details ?: any) => any>>();
public constructor(private http: HttpClient)
{
}
public post<T>(path : string, data : any, urlParams : any = null) : Observable<any>
{
return this.http.post<T>(`${environment.api.path}${path}`, data, {
params: urlParams
}).catch(this.catchErrors()).map(response => {
if (response['Error']){
throw response['Error'];
}
return response;
});
}
}
--
Component
#Component({
selector: 'login-register-component',
templateUrl: './register.component.html',
styleUrls: [
'./../../assets/main/css/pages/login.css'
]
})
export class RegisterComponent implements OnInit, OnDestroy
{
public constructor(private route: ActivatedRoute,
private router: Router,
private userService : UserService,
private apiService: ApiService
)
{
this.apiService.post('/some-endpoint', null, {}).subscribe(res => {
console.log(res);
});
}
HttpClient does not work even if i directly inject HttpClient into Component
-- Other component in the same module
example call: (it works)
public loginTraditionalMethod(emailAddress : string, plainPassword : string)
{
this.apiService.post('/auth/email', {
email: emailAddress,
password: plainPassword
}, {}).subscribe(res => {
console.log(res);
})
}
I was having the same problem, no xhr request after subscribing to a http.get(). This was a request for a forgotten password function, I was therefore not connected to the app.
The request was being intercepted by an http token interceptor that was returning an empty Observable if no session was detected.
Never know, this might help someone...

Resources