Unexpected type error in websockets when compiling nest js project - websocket

Below is my code
I tried to set a web socket gateway as below.
events.gateways.ts
import {
MessageBody,
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
} from "#nestjs/websockets";
import { Server } from "socket.io";
#WebSocketGateway({
cors: {
origin: "http://localhost:3000",
},
})
export class EventsGateway {
#WebSocketServer()
server: Server;
#SubscribeMessage("events")
handleEvent(#MessageBody() data: string): string {
return data;
}
}
I set above gateway as a provider to a module.
events.module.ts
import { Module } from "#nestjs/common";
import { EventsGateway } from "./events.gateway";
#Module({
providers: [EventsGateway],
})
export class EventsModule {}
Fianllt, i imported above module to the app.module.ts and now I am getting the error
app.module.ts
import { Module } from "#nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { APP_FILTER } from "#nestjs/core";
import { AllExceptionFilter } from "./all-exception.filter";
import { ConfigModule } from "#nestjs/config";
import { TypeOrmModule } from "#nestjs/typeorm";
import { Student } from "./student/entities/student.entity";
import { EventsModule } from "./events/events.module";
#Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forRoot({
type: "postgres",
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT as string) | 5432,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
entities: [Student],
synchronize: true,
}),
EventsModule,
],
controllers: [AppController],
providers: [
{
provide: APP_FILTER,
useClass: AllExceptionFilter,
},
AppService,
],
})
export class AppModule {}
This is the error I am keep getting.
TypeError: this.graphInspector.insertEntrypointDefinition is not a function
at /home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/web-sockets-controller.js:108:33
at Array.forEach (<anonymous>)
at WebSocketsController.inspectEntrypointDefinitions (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/web-sockets-controller.js:106:25)
at WebSocketsController.subscribeToServerEvents (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/web-sockets-controller.js:39:14)
at WebSocketsController.connectGatewayToServer (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/web-sockets-controller.js:30:14)
at SocketModule.connectGatewayToServer (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/socket-module.js:47:35)
at /home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/socket-module.js:36:38
at IteratorWithOperators.forEach (/home/Desktop/New Folder/nest_try_1/node_modules/iterare/lib/iterate.js:157:13)
at SocketModule.connectAllGateways (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/socket-module.js:36:14)
at /home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/socket-module.js:31:61
Node.js v19.4.0
I am follwing the documentation and I am keep getting above error.

you should align your dependencies, ie., if you're using #nestjs/websockets v9.3.1, #nestjs/core must be in v9.3.1 as well
Run npx nest info and check that out.
That error is because #nestjs/websockets is invoking a method added in v9.3 which depends on a method added in v9.3 of #nestjs/core as well.
btw there are closed issues on GitHub about that error: https://github.com/nestjs/nest/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aclosed+insertEntrypointDefinition

Related

Nestjs Hybrid application websocket + microservice

I have a problem with Nestjs, with starting a microservice that listens to a messagebroker, while simultaneously starting a websocket server with which we can communicate with front-end clients.
So I am aware of hybrid nest applications, where the websocket gateway can be injected into the microservice. However I get errors about Nest not being able to resolve the Gateway import.
I configured the microservice in a ResultsModule, the websocket in UsersModule.
The error I get is:
ERROR [ExceptionHandler] Nest can't resolve dependencies of the ResultsController (ResultsService, ?). Please make sure that the argument UsersGateway at index [1] is available in the ResultsModule context.
These are the relevant pieces of code:
main.js
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.connectMicroservice<MicroserviceOptions>({
transport: Transport.RMQ,
options: {
urls: [
`amqp://${config.rabbitmq.username}:${config.rabbitmq.password}#${config.rabbitmq.host}:${config.rabbitmq.port}`,
],
queue: config.rabbitmq.channelListen,
noAck: false,
queueOptions: {
durable: false,
},
},
});
await app.startAllMicroservices();
await app.listen(82);
}
bootstrap();
app.module.ts
#Module({
imports: [UsersModule, ResultsModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
results.module.ts
#Module({
imports: [UsersModule],
controllers: [ResultsController],
providers: [ResultsService],
})
export class ResultsModule {}
users.module.ts
#Module({
providers: [UsersGateway, UsersService],
})
export class UsersModule {}
users.gateway.ts
import {
WebSocketGateway,
SubscribeMessage,
MessageBody,
OnGatewayInit,
OnGatewayConnection,
OnGatewayDisconnect,
WebSocketServer,
ConnectedSocket,
} from '#nestjs/websockets';
import { Socket, Server } from 'socket.io';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
#WebSocketGateway(82)
export class UsersGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
constructor(private readonly usersService: UsersService) {}
#WebSocketServer() server: Server;
afterInit(server: Server) {
console.log('init');
}
handleDisconnect(client: Socket) {
console.log(`Client disconnected: ${client.id}`);
}
handleConnection(client: Socket, ...args: any[]) {
console.log(client.id);
}
#SubscribeMessage('resource')
create(
#MessageBody() createUserDto: CreateUserDto,
#ConnectedSocket() client: Socket,
) {
console.log(client.id);
console.log(createUserDto.resourceId)
}
}
I tried to move around the imports, not wrapping the gateway in a module.
Tried moving the results module out of the app.module. Which removes the error, however then I do not understand where to let nestjs know to use the resultsmodule for the microservice.
------------------------ANSWER-------------------------------------
Alright, we fixed it with the help of #yomateo , we were missing the export of the websocket gateway in the module. Thanks for the help!
You're close (you have it backwards).
Have your UsersGateway or UsersService call the ResultsService.

Confused about AngularFire Functions modules and imports

I spun up a new project with Angular and AngularFire. I ran
firebase init firestore
firebase init functions
This set up this Angular module:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { initializeApp,provideFirebaseApp } from '#angular/fire/app';
import { environment } from '../environments/environment';
import { provideFirestore,getFirestore } from '#angular/fire/firestore';
import { provideFunctions,getFunctions } from '#angular/fire/functions';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => getFirestore()),
provideFunctions(() => getFunctions())
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
I didn't write any of that. It looks like AngularFire 7.
The AngularFire Functions documentation shows a different module setup. It looks like AngularFire 6:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { AngularFireModule } from '#angular/fire/compat';
import { AngularFireFunctionsModule } from '#angular/fire/compat/functions';
import { environment } from '../environments/environment';
#NgModule({
imports: [
BrowserModule,
AngularFireModule.initializeApp(environment.firebase),
AngularFireFunctionsModule
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
The differences are that the new module has:
import { initializeApp,provideFirebaseApp } from '#angular/fire/app';
import { provideFirestore,getFirestore } from '#angular/fire/firestore';
import { provideFunctions,getFunctions } from '#angular/fire/functions';
...
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => getFirestore()),
provideFunctions(() => getFunctions())
There are two extra lines because I initialized Firestore. The older module has this:
import { AngularFireModule } from '#angular/fire/compat';
import { AngularFireFunctionsModule } from '#angular/fire/compat/functions';
...
AngularFireModule.initializeApp(environment.firebase),
AngularFireFunctionsModule
I left the new module as is and went on to the component. Here's what the AngularFire Functions documentation says to use this (I added a template and stylesheet):
import { Component } from '#angular/core';
import { AngularFireFunctions } from '#angular/fire/compat/functions';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private functions: AngularFireFunctions) { }
}
That component throws an error message:
R3InjectorError(AppModule)[AngularFireFunctions -> InjectionToken
It can't inject AngularFireFunctions.
I went back to the module and added these lines:
import { AngularFireFunctionsModule } from '#angular/fire/compat/functions';
...
imports: [
...
AngularFireFunctionsModule
],
That doesn't fix the error. The error only goes away when I add this code to the module:
import { AngularFireModule } from '#angular/fire/compat';
import { AngularFireFunctionsModule } from '#angular/fire/compat/functions';
...
imports: [
BrowserModule,
// provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => getFirestore()),
provideFunctions(() => getFunctions()),
AngularFireModule.initializeApp(environment.firebase),
AngularFireFunctionsModule
],
In other words, I commented out the AngularFire 7 version of initializeApp and used the AngularFire 6 version of initializeApp.
This code is getting smelly. It seems to me that I should leave the module alone and in the component I should import httpsCallable and AngularFireFunctions from #angular/fire/functions. No problem importing httpsCallable but AngularFireFunctions isn't on #angular/fire/functions.
I feel like the component should look like this:
import { Component } from '#angular/core';
import { Firestore, doc, getDoc, getDocs, collection, updateDoc } from '#angular/fire/firestore';
import { httpsCallable, AngularFireFunctions } from '#angular/fire/functions';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private functions: AngularFireFunctions) {}
callMe() {
console.log("Calling...");
this.functions.httpsCallable('helloWorld');
}
}
The problem is in AngularFireFunctions. Has this been replaced with something new in AngularFire 7?
I looked through the AngularFire repo on GitHub looking for #angular/fire/functions but I couldn't find this. Where can I see the properties on this type?
There's no AngularFire 7 module for Functions. Use the Firebase module:
import { getFunctions, httpsCallable, httpsCallableFromURL } from "firebase/functions";

When I run nest.js, I get a Missing "driver" option error

I am using nest.js, prisma, and graphql.
When I run the npm run start:dev command, I get an error.
If anyone knows how to solve this, please let me know.
ERROR [GraphQLModule] Missing
"driver" option. In the latest version of "#nestjs/graphql" package
(v10) a new required configuration property called "driver" has been
introduced. Check out the official documentation for more details on
how to migrate (https://docs.nestjs.com/graphql/migration-guide).
Example:
GraphQLModule.forRoot({
driver: ApolloDriver,
})
app.module.ts
import { Module } from '#nestjs/common';
import { GraphQLModule } from '#nestjs/graphql';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ApolloServerPluginLandingPageLocalDefault } from 'apollo-server-core';
import { DonationsModule } from './donations/donations.module';
#Module({
imports: [
GraphQLModule.forRoot({
playground: false,
plugins: [ApolloServerPluginLandingPageLocalDefault()],
typePaths: ['./**/*.graphql'],
}),
DonationsModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
generate-typings.ts
import { GraphQLDefinitionsFactory } from '#nestjs/graphql';
import { join } from 'path';
const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
typePaths: ['./src/**/*.graphql'],
path: join(process.cwd(), 'src/graphql.ts'),
outputAs: 'class',
watch: true,
});
fix
#Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: true,
plugins: [ApolloServerPluginLandingPageLocalDefault()],
typePaths: ['./**/*.graphql'],
}),
DonationsModule,
],
controllers: [AppController],
providers: [AppService],
})
Checkout the nestjs/graphql documentation page and the other link that you have mentioned. You have to configure your GraphQLModule like this which I don't see in your code.
#Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
}),
],
})
Also don't forget to import
import { ApolloDriverConfig, ApolloDriver } from '#nestjs/apollo';

document is not defined when do "tns test android"

I create a login.component.spec.ts for my loginComponent. However, when I run tns test android, the TestBed.createComponent(LoginComponent) failed. The error is below:
NativeScript / 29 (10; Android SDK built for x86) LoginComponent
Should create the app FAILED
Failed: StaticInjectorError(DynamicTestModule)[TestComponentRenderer
-> InjectionToken DocumentToken]:
StaticInjectorError(Platform: core)[TestComponentRenderer ->
InjectionToken DocumentToken]: document is not defined
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [
'TestComponentRenderer', InjectionToken DocumentToken ] }) at Jasmine
I cannot find any result in website about my problem. Thanks for helping.
I tried to include http module since someone said the undefined document may because of http. However, it still does not work.
This is code for login.component.spec.ts:
import "core-js";
import "zone.js/dist/zone";
import "zone.js/dist/proxy";
import "zone.js/dist/sync-test";
import "zone.js/dist/async-test";
import "zone.js/dist/fake-async-test";
import "zone.js/dist/jasmine-patch";
import "zone.js/dist/long-stack-trace-zone";
import { ComponentFixture, async, TestBed} from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { NO_ERRORS_SCHEMA, DebugElement} from '#angular/core';
import { RouterTestingModule } from '#angular/router/testing';
import { Router } from '#angular/router';
import { ActivatedRoute } from "#angular/router";
import { RouterExtensions } from "nativescript-angular/router";
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting }
from '#angular/platform-browser-dynamic/testing';
import { LoginComponent } from '~/pages/login/login.component';
describe ('LoginComponent', () => {
beforeEach(async( () => {
TestBed.resetTestEnvironment();
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
providers: [],
declarations: [
LoginComponent
],
schemas: [
NO_ERRORS_SCHEMA]
}).compileComponents();
}));
it('Should create the app', async( () => {
const fixture = TestBed.createComponent(LoginComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
});
You are using the BrowserDynamicTestingModule which is not valid for {N}. You are suppose to use NativeScriptTestingModule form nativescript-angular/testing.

How to only expose part of prima generated schema in nestjs

I'm trying to integrate nestjs with prisma. I followed the tutorial in nestjs document.
Everthing works fine until I want to make some changes so nestjs doesn't expose all the query/mutations schema.
what I did is
1. update app module not let typePath include the generated schema
import { Module } from '#nestjs/common';
import { AppController } from 'app/app.controller';
import { AppService } from 'app/app.service';
import { GraphQLModule } from '#nestjs/graphql';
import { UserModule } from './user/user.module';
#Module({
imports: [
GraphQLModule.forRoot({
typePaths: ['./src/**/*.schema.graphql'],
debug: true,
playground: true,
}),
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
2. Then I created a user.schema.graphql file in user folder:
#import User from "../prisma/generated/prisma.graphql"
type Query {
user(id: ID!): User
}
However, I got some error saying I can't import User:
(node:36277) UnhandledPromiseRejectionWarning: Error: Type "User" not found in document.
at ASTDefinitionBuilder._resolveType (/Users/anx/Projects/axesk/gallery-api/node_modules/graphql/utilities/buildASTSchema.js:100:11)
at ASTDefinitionBuilder.buildType (/Users/anx/Projects/axesk/gallery-api/node_modules/graphql/utilities/buildASTSchema.js:210:79)
at ASTDefinitionBuilder._buildWrappedType (/Users/anx/Projects/axesk/gallery-api/node_modules/graphql/utilities/buildASTSchema.js:229:17)
at ASTDefinitionBuilder.buildField (/Users/anx/Projects/axesk/gallery-api/node_modules/graphql/utilities/buildASTSchema.js:249:18)
at /Users/anx/Projects/axesk/gallery-api/node_modules/graphql/utilities/buildASTSchema.js:332:21
at /Users/anx/Projects/axesk/gallery-api/node_modules/graphql/jsutils/keyValMap.js:36:31
at Array.reduce (<anonymous>)
at keyValMap (/Users/anx/Projects/axesk/gallery-api/node_modules/graphql/jsutils/keyValMap.js:35:15)
at ASTDefinitionBuilder._makeFieldDefMap (/Users/anx/Projects/axesk/gallery-api/node_modules/graphql/utilities/buildASTSchema.js:329:48)
at fields (/Users/anx/Projects/axesk/gallery-api/node_modules/graphql/utilities/buildASTSchema.js:312:22)
(node:36277) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:36277) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I'm new to nestjs and graphql, please help!
I make it work in sort of hack way.. i will just paste my solution here for anyone who got same problem.
For example i have a user.schema.graphql that import some type from prisma.graphql:
#import User from "../prisma/generated/prisma.graphql"
type Query {
user(id: ID!): User
}
Then i create a main.schema.graphql file that will import every schemas from the project manually.
#import * from "./user/user.schema.graphql"
Finally just import this maim schema to app.module.ts:
import { Module } from '#nestjs/common';
import { AppController } from 'app/app.controller';
import { AppService } from 'app/app.service';
import { GraphQLModule } from '#nestjs/graphql';
import { UserModule } from './user/user.module';
import { importSchema } from 'graphql-import';
#Module({
imports: [
GraphQLModule.forRoot({
resolverValidationOptions: {
requireResolversForResolveType: false,
},
typeDefs: importSchema('./src/main.schema.graphql'),
debug: true,
playground: true,
}),
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Doing this not really ideal. if graphql-import library can import from folders, it makes life easier.
or the #nest/graphql library can use graphql-import instead of merge-graphql-schemas under the hood to build typeDefs will be also great.

Resources