Angular 2+ modal popup timer and redirect - node.js

I want to make a request on mongodb and while the request is loading I want a modal windows popup with a hourglass who leave when the request is ending and redirect on an other route if possible.
Angular 2+
NodeJS
MongoDB
I have the modal windows popup ready.
Edit : Easy way
I found by adding a "dialogRef.close() in the res"
this.countModelService.getCount(datas)
.subscribe(res =>
{
dialogRef.close();
});

This is more angular related than node.js ... Imagine you have your mongoDB request implemented as an angular service mongoService. Imagine, your popup is done with ng-bootstrap - NgbModal. Then the client side code could look like this:
import { Component, Inject, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { MongoService } from './services/mongo.service';
#Component({
selector: 'app-mycomp',
templateUrl: './mycomp.component.html',
styleUrls: ['./mycomp.component.scss']
})
export class MycompComponent implements OnInit, ... {
mr: NgbModalRef;
constructor(...
private mongo: MongoService,
private modalService: NgbModal,
...) {
}
ngOnInit() {
// some initialization ...
}
getFromDB() { // <--- this is the function you call when clicking your button
this.mr = this.modalService.open(content);
mongo.getData().subscribe(
data => {
// ... your data handling ...
this.mr.close();
this.router.navigate(['/anotherroute']);
},
error => {
// ... your error handling ...
this.mr.close();
}
)
}
}
CSS-Styling with hourglass should then be something like
...
cursor: wait;
...

Related

use Effect not working in react. the error is saying Uexpected token in the web console

I am using use effect in react js and it seems that it has a problem if I use 'effect'
in my react app then it gives me an error saying "Unexpected token"
import React, { Component , useEffect} from 'react'
class Effect extends Component {
useEffect(() => {
console.log('Effect');
})
constructor() {
super()
this.state =
{
count :0
}
this.CH = () =>
{
this.setState(PS =>{
console.log(PS);
return {count:PS.count +1}
})
}
}
render()
{
return(
<>
<button onClick={this.CH}>
</button>
<p>
{`You have clicked me ${this.state.count} times.`}
</p>
</>
)
}
}
export default Effect
and this is the useEffect code:
useEffect(() => {
console.log('Effect');
})
so i followed some vids and it seems to not work for me
they were using this in function based component . but i am not,
so the the problem us this only?
You can only use useEffect on Functional-based components!
On class-based you have some alternatives: componentDidMount()
Docs: https://reactjs.org/docs/react-component.html#componentdidmount
Suggestion: if you are creating a new react app most of the time the best thing to do is to use function components.
Source: https://djoech.medium.com/functional-vs-class-components-in-react-231e3fbd7108#:~:text=The%20most%20obvious%20one%20difference,which%20returns%20a%20React%20element.

how can I do handling in nestjs when not caught

I am using nestjs.
I have created an AllExceptionFilter.
However, once I run the post request api on the httpService and then an error is returned
nestjs will not accept the RESTful API after that.
What should I do?
■ error log
/Users/username/Documents/workspace/project/nestjs/src/shared/filters/custom-exception.filter.ts:29
path: httpAdapter.getRequestUrl(ctx.getRequest()),
^
TypeError: Cannot read properties of undefined (reading 'getRequestUrl')
at AllExceptionsFilter.catch (/Users/username/Documents/workspace/project/nestjs/src/shared/filters/custom-exception.filter.ts:29:25)
at ExceptionsHandler.invokeCustomFilters (/Users/username/Documents/workspace/project/nestjs/node_modules/#nestjs/core/exceptions/exceptions-handler.js:33:26)
at ExceptionsHandler.next (/Users/username/Documents/workspace/project/nestjs/node_modules/#nestjs/core/exceptions/exceptions-handler.js:13:18)
at /Users/username/Documents/workspace/project/nestjs/node_modules/#nestjs/core/router/router-proxy.js:13:35
at processTicksAndRejections (node:internal/process/task_queues:96:5)
■ no try/catch point code
await firstValueFrom(this.httpService.post(
url,
{
id: 'id'
},
));
■ AllExceptionFilter
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
} from '#nestjs/common';
import { HttpAdapterHost } from '#nestjs/core';
#Catch()
export class AllExceptionsFilter implements ExceptionFilter {
constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
catch(exception: unknown, host: ArgumentsHost): void {
// In certain situations `httpAdapter` might not be available in the
// constructor method, thus we should resolve it here.
const { httpAdapter } = this.httpAdapterHost;
const ctx = host.switchToHttp();
const httpStatus =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
const responseBody = {
statusCode: httpStatus,
timestamp: new Date().toISOString(),
path: httpAdapter.getRequestUrl(ctx.getRequest()),
};
httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);
}
}
Looks like an error is thrown by your endpoint, and the exception filter has an error that is triggered when attempting to handle the first exception.
As specified in the stack trace, the error is coming from: custom-exception.filter.ts:29, which is this line: path: httpAdapter.getRequestUrl(ctx.getRequest())
The problem is that httpAdapter in that line is undefined. For some reason DI isn't injecting it.
If you're using this filter globally, note the following from the docs:
Global-scoped filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from outside of any module (with useGlobalFilters() as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can register a global-scoped filter directly from any module using the following construction:
import { Module } from '#nestjs/common';
import { APP_FILTER } from '#nestjs/core';
#Module({
providers: [
{
provide: APP_FILTER,
useClass: HttpExceptionFilter,
},
],
})
export class AppModule {}
If you use the above approach you won't need the useGlobalFilters() method.
If you want to bind this filter at the controller level, the following syntax enables DI:
#UseFilters(AllExceptionsFilter)
#Controller("app")
export class AppController {

How to pass a #liaoliaots/nestjs-redis redis connection to global guard constructor

i'm new in NestJS and have some misunderstands with #liaoliaots/nestjs-redis(https://github.com/liaoliaots/nestjs-redis) package. For example, i have a guard with following constructor:
import { InjectRedis } from '#liaoliaots/nestjs-redis';
import { Redis } from 'ioredis';
#Injectable()
export class SomeGuard implements CanActivate {
constructor(#InjectRedis() redis: Redis) {}
...
}
and then i want that guard to be global:
//main.ts
...
app.useGlobalGuards(new SomeGuard(/* what??? */));
...
so thats a problem: what i need to pass? #InjectRedis makes weird things:)
thx for responding
Instead of app.useGlobalGuards, use this another way:
// ...
import { Module } from '#nestjs/common'
import { APP_GUARD } from '#nestjs/core'
#Module({
// ...
providers: [
{
provide: APP_GUARD,
useClass: SomeGuard,
},
],
})
export class AppModule {}
is cleaner and helps you avoid polluting your boostrap funcion. Also, it lets Nest resolves that Redis dependency. Otherwise you'll need to get this dependency and pass it to new SomeGuard using
const redis = app.get(getRedisToken())
https://docs.nestjs.com/guards#binding-guards

Create React App and JEST property matchers

I've got this component that I've simplified for this example as part of a bigger create react app
import React from 'react';
function myVersion() {
return (
<p className={'ActivateSound--para'} data-testid={`version`}>
Version {process.env.REACT_APP_VERSION} has loaded, congrats!
</p>
);
}
export { myVersion };
and in the env I get the version from package.json
REACT_APP_VERSION=$npm_package_version
but in the test I've got
import React from 'react';
import { myVersion } from '../components/my-version';
import { render, screen, cleanup, fireEvent } from '#testing-library/react';
afterEach(cleanup);
describe('my version component', () => {
test('snapshot hasnt changed', () => {
expect(container.firstChild).toMatchSnapshot();
});
});
I am now looking at https://jestjs.io/docs/snapshot-testing#property-matchers. It seems I can exclude the version number somehow, I've tried a bunch of attempts but it's not ignoring the version number
expect(container.firstChild).toMatchSnapshot({
screen.getByTestId('version'): expect.any(String)
});

Programatically declare RabbitMQ consumers in NestJS / Node.js?

I am using a NestJS application to consume a RabbitMQ queue.
Each message can be processed no matter the order, so I'm wondering what would be the best practise to declare new consumers for the same queue.
Expected behaviour: The queue is processed by this service, which is using several consumers
Queue: [1,2,3,4,5,6, ...N];
In nestJS you can use the #RabbitSubscribe decorator to assign a function to process the data. What I want to do could be achieved by simply duplicating (and renaming) the function with the decorator, so this function will also be called to process data from the queue
#RabbitSubscribe({
...
queue: 'my-queue',
})
async firstSubscriber(data){
// 1, 3, 5...
}
#RabbitSubscribe({
...
queue: 'my-queue',
})
async secondSubscriber(data){
// 2, 4, 6...
}
I am aware that I could duplicate the project and scale horizontally, but I'd prefer doing this on the same process.
How could I declare subscribers to get this same behaviour programatically, so I could process the data with more concurrent processing?
You will benefit if you use #golevelup/nestjs-rabbitmq package as its supports different messages queque consumption and more if your app is hybrid.
First install
npm i #golevelup/nestjs-rabbitmq
then your nestjs app structure should look like this
src --
|
app.module.ts
main.ts
app.module.ts
someHttpModule1 --
|
someHttpModule1.controller.ts
someHttpModule1.module.ts
someHttpModule1.service.ts
...
someHttpModule2 --
|
someHttpModule2.controller.ts
someHttpModule2.module.ts
someHttpModule2.service.ts
...
...
// Events module is designed for consuming messages from rabbitmq
events --
|
events.module.ts
someEventConsumerModule1 --
|
someEventConsumerModule1.module.ts
someEventConsumerModule1.service.ts
someEventConsumerModule2 --
|
someEventConsumerModule2.module.ts
someEventConsumerModule2.service.ts
...
In the src/app.module.ts file
// module imports
import { SomeHttpModule1 } from './someHttpModule1/someHttpModule1.module'
import { SomeHttpModule2 } from './someHttpModule2/someHttpModule.module'
import { EventsModule } from './events/events.module'
// and other necessery modules
#Module(
imports: [
SomeHttpModule1,
SomeHttpModule2,
EventsModule,
// and other dependent modules
],
controller: [],
providers: []
})
export class AppModule{}
And in your events.module.ts file
// imports
import { RabbitMQModule } from '#golevelup/nestjs-rabbitmq'
import { SomeEventConsumerModule1 } from './someEventConsumerModule1/someEventConsumerModule1.module'
import { SomeEventConsumerModule2 } from './someEventConsumerModule2/someEventConsumerModule2.module'
// and so on
#Module({
imports: [
RabbitMQModule.forRoot(RabbitMQModule, {
exchanges: [{
name: 'amq.direct',
type: 'direct' // check out docs for more information on exchange types
}],
uri: 'amqp://guest:guest#localhost:5672', // default login and password is guest, and listens locally to 5672 port in amqp protocol
connectionInitOptions: { wait: false }
}),
SomeEventConsumerModule1,
SomeEventConsumerModule2,
// ... and other dependent consumer modules
]
})
export class EventsModule {}
And below is example for one consumer module (someEventConsumerModule1.module.ts)
// imports
import { SomeEventConsumerModule1Service } from './someEventConsumerModule1.service'
// ...
#Module({
imports: [
SomeEventConsumerModule1,
// other modules if injected
],
providers: [
SomeEventConsumerModule1Service
]
})
export class SomeEventConsumerModule1 {}
And in your service file put your business logic how to handle messages
// imports
import { RabbitSubscribe } from '#golevelup/nestjs-rabbitmq'
import { Injectable } from '#nestjs/common'
import { ConsumeMessage, Channel } from 'amqplib' // for type safety you will need to install package first
// ... so on
#Injectable()
export class SomeEventConsumerModule1Service {
constructor(
// other module services if needs to be injected
) {}
#RabbitSubscribe({
exchange: 'amq.direct',
routingKey: 'direct-route-key', // up to you
queue: 'queueNameToBeConsumed',
errorHandler: (channel: Channel, msg: ConsumeMessage, error: Error) => {
console.log(error)
channel.reject(msg, false) // use error handler, or otherwise app will crush in not intended way
}
})
public async onQueueConsumption(msg: {}, amqpMsg: ConsumeMessage) {
const eventData = JSON.parse(amqpMsg.content.toString())
// do something with eventData
console.log(`EventData: ${eventData}, successfully consumed!`)
}
// ... and in the same way
}

Resources