I’m trying to implement express-session
package along with connect-redis
for session storage in my NestJS backend, but i got such an error as follows. I even changed the client inside the store to RedisClient
, which is injection token declared in provider file, but still no luck, where im mistaken exactly? whats the best practises to implement such feature so that I can use redis as session storage, either using connect-redis
or something else…thanks a lot in advance, any help appreciated
error message:
store: new ((0, connect_redis_1.default)(session))({
^
TypeError: Class constructor RedisStore cannot be invoked without 'new'
ERROR in ./src/app.module.ts:34:5
TS2322: Type 'RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' is not assignable to type 'Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference<any>'.
32 | CartModule,
33 | RedisModule,
> 34 | session({
| ^^^^^^^^^
> 35 | store: new (RedisStore(session))({
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 36 | client: redisClientFactory,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 37 | }),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 38 | secret: 'my-secret',
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 39 | resave: false,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 40 | saveUninitialized: false,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 41 | }),
| ^^^^^^^
42 | ],
43 | controllers: [AppController],
44 | providers: [AppService, AccessControlService, ReviewService],
ERROR in ./src/app.module.ts:35:19
TS2348: Value of type 'typeof RedisStore' is not callable. Did you mean to include 'new'?
33 | RedisModule,
34 | session({
> 35 | store: new (RedisStore(session))({
| ^^^^^^^^^^^^^^^^^^^
36 | client: redisClientFactory,
37 | }),
38 | secret: 'my-secret',
app.module.ts
import { Module, Inject, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { LoggerModule } from '@app/common';
import { ConfigModule } from '@app/common';
import { DatabaseModule } from './database/database.module';
import { AuthModule } from './auth/auth.module';
import { UserModule } from './user/user.module';
import { ProductModule } from './product/product.module';
import { CategoryModule } from './category/category.module';
import { Role } from '@prisma/client';
import { AccessControlService } from '@app/common/access-control/access-control.service';
import { SearchModule } from '@app/common/elastic-search/elasticsearch.module';
import { ReviewService } from './review/review.service';
import { ReviewModule } from './review/review.module';
import { CartModule } from './cart/cart.module';
import RedisStore from 'connect-redis';
import * as session from 'express-session';
import { RedisModule } from '@app/common/redis/redis.module';
import { redisClientFactory } from '@app/common/redis/redis.provider';
@Module({
imports: [
LoggerModule,
ConfigModule,
DatabaseModule,
AuthModule,
UserModule,
ProductModule,
CategoryModule,
ReviewModule,
CartModule,
RedisModule,
session({
store: new (RedisStore(session))({
client: redisClientFactory,
}),
secret: 'my-secret',
resave: false,
saveUninitialized: false,
}),
],
controllers: [AppController],
providers: [AppService, AccessControlService, ReviewService],
})
export class AppModule {}
redis.module.ts
import { Module } from '@nestjs/common';
import { RedisRepository } from './redis.repository';
import { RedisService } from './redis.service';
import { redisClientFactory } from './redis.provider';
@Module({
providers: [RedisService, RedisRepository, redisClientFactory],
exports: [RedisService, RedisRepository, redisClientFactory],
})
export class RedisModule {}
redis.provider.ts
import { FactoryProvider } from '@nestjs/common';
import { Redis } from 'ioredis';
import { ConfigService } from '@nestjs/config';
export const redisClientFactory: FactoryProvider<Redis> = {
provide: 'RedisClient',
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
const redisInstance = new Redis({
host: configService.get('REDIS_HOST'),
port: configService.get('REDIS_PORT'),
password: configService.get('REDIS_PASSWORD'),
});
redisInstance.on('error', (error) => {
console.error('Redis error', error);
});
return redisInstance;
},
};
even changed the client inside the store to RedisClient, which is injection token declared in provider file
2
Answers
Not familiar with the library, but this looks like a garden-variety TypeScript error to me. The
RedisStore
class is a class and requires thenew
operator to instantiate it. However, it’s being invoked like a function inside of the parentheses.I’d try moving the
new
and see if the error changes:Hope this helps.