HttpClient Angular 5 does not send request - ajax

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...

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.

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

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";

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,
),
);
}
}

Spring stomp over websocket SubscribeMapping not working

I'm trying to configure subscription mapping for stomp over websockets in a spring boot application without any luck. I'm fairly certian I have the stomp/websocket stuff configured correctly as I am able to subscribe to topics that are being published to by a kafka consumer, but using the #SubscribeMapping is not working at all.
Here is my controller
#Controller
class TestController {
#SubscribeMapping("/topic/test")
fun testMapping(): String {
return "THIS IS A TEST"
}
}
And here is my configuration
#Configuration
#EnableWebSocketMessageBroker
#Order(Ordered.HIGHEST_PRECEDENCE + 99)
class WebSocketConfig : AbstractWebSocketMessageBrokerConfigurer() {
override fun configureMessageBroker(config: MessageBrokerRegistry) {
config.setApplicationDestinationPrefixes("/app", "/topic")
config.enableSimpleBroker("/queue", "/topic")
config.setUserDestinationPrefix("/user")
}
override fun registerStompEndpoints(registry:StompEndpointRegistry) {
registry.addEndpoint("/ws").setAllowedOrigins("*")
}
override fun configureClientInboundChannel(registration: ChannelRegistration?) {
registration?.setInterceptors(object: ChannelInterceptorAdapter() {
override fun preSend(message: Message<*>, channel: MessageChannel): Message<*> {
val accessor: StompHeaderAccessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor::class.java)
if (StompCommand.CONNECT.equals(accessor.command)) {
Optional.ofNullable(accessor.getNativeHeader("authorization")).ifPresent {
val token = it[0]
val keyReader = KeyReader()
val creds = Jwts.parser().setSigningKey(keyReader.key).parseClaimsJws(token).body
val groups = creds.get("groups", List::class.java)
val authorities = groups.map { SimpleGrantedAuthority(it as String) }
val authResult = UsernamePasswordAuthenticationToken(creds.subject, token, authorities)
SecurityContextHolder.getContext().authentication = authResult
accessor.user = authResult
}
}
return message
}
})
}
}
And then in the UI code, I'm using angular with a stompjs wrapper to subscribe to it like this:
this.stompService.subscribe('/topic/test')
.map(data => data.body)
.subscribe(data => console.log(data));
Subscribing like this to topics that I know are emitting data works perfectly but the subscribemapping does nothing. I've also tried adding an event listener to my websocket config to test that the UI is actually sending a subscription event to the back end like this:
#EventListener
fun handleSubscribeEvent(event: SessionSubscribeEvent) {
println("Subscription event: $event")
}
#EventListener
fun handleConnectEvent(event: SessionConnectEvent) {
println("Connection event: $event")
}
#EventListener
fun handleDisconnectEvent(event: SessionDisconnectEvent) {
println("Disconnection event: $event")
}
Adding these event listeners I can see that all the events that I'm expecting from the UI are coming through in the kotlin layer, but my controller method never gets called. Is there anything obvious that I'm missing?
Try the following:
#Controller
class TestController {
#SubscribeMapping("/test")
fun testMapping(): String {
return "THIS IS A TEST"
}
}

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'))

Resources