tekuila
tekuila

Reputation: 111

TypeError: store.get is not a function - NestJs, cache-manager

I'm implementing caching following the NestJS docs.

Create new project for this so there's no difference between docs example and this.

  1. imports CacheModule.. just like docs
import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

  1. Inject CacheManager..
import { CACHE_MANAGER, Controller, Get, Inject } from '@nestjs/common';
import { Cache } from 'cache-manager';

@Controller()
export class AppController {
  constructor(
    @Inject(CACHE_MANAGER) private cacheManager: Cache,
  ) {}
}
  1. And use it
  @Get()
  async getHello(): Promise<string> {
    const value: string = await this.cacheManager.get('hello');
    if (value === null) {
      await this.cacheManager.set('hello', 'cache item', 60);
      return 'no cache exists';
    }
    return value;
  }

but I get this error, I don't know why:

TypeError: store.get is not a function
    at Object.get (.../node_modules/cache-manager/src/caching.ts:88:36)
    at AppController.getHello

This is a simple job, I think.

So there's no one seems to get this error (I looked it up).

Upvotes: 11

Views: 16432

Answers (7)

Chpotl
Chpotl

Reputation: 11

This worked for me

"cache-manager": "^5.7.6",

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { CacheManagerOptions, CacheModule, CacheStore } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-redis-store';

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: [`.env.${process.env.NODE_ENV}`],
      validationSchema: configValidationSchema,
      isGlobal: true,
    }),
    CacheModule.registerAsync({
      isGlobal: true,
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService): Promise<CacheManagerOptions> => {
        const store = await redisStore({
          url: configService.getOrThrow('REDIS_URL'),
        });
        return { store: store as unknown as CacheStore };
      },
      inject: [ConfigService],
    }),
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

Upvotes: 0

ninoorta
ninoorta

Reputation: 1028

Because of the version of cache-manager and redis and some notes from Nestjs docs cache-manager-redis-store does not support redis v4. I found most of solutions were not working with my case

Thus,here is my working one, hope this can help somebody ^^

import { CacheModule } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-redis-store';

CacheModule.registerAsync({
            isGlobal: true,
            imports: [ConfigModule],
            useFactory: async (configService: ConfigService) => {
                const host = configService.get<string>('redis.host');
                const port = Number(configService.get<string>('redis.port'));

                return {
                    store: (): any =>
                        redisStore({
                            socket: {
                                host,
                                port,
                            },
                        }),
                };
            },
            inject: [ConfigService],
        }),

My service that uses redis

import { CACHE_MANAGER, CacheStore } from '@nestjs/cache-manager';    
@Injectable()
    export class AuthService {
        constructor(
            private configService: ConfigService,
            @Inject(CACHE_MANAGER) private cacheService: CacheStore,
        ) {}

My package.json

"@nestjs/cache-manager": "^2.2.2",
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/swagger": "^7.3.0",
"@types/redis": "^4.0.11",
"bcrypt": "^5.1.1",
"cache-manager": "^5.5.1",
"cache-manager-redis-store": "^3.0.1",
"redis": "3.1.2",

Upvotes: 2

Huboh
Huboh

Reputation: 135

I encountered a similar issue last year and couldn't find a proper solution. In the end, I had to resort to downgrading to a previous version, as mentioned in some of the previous answers. However, today I faced the same problem again and after couple of hours...

for newer versions of cache-manager, this should work:

NB: the example demonstrate a custom nestjs cache service to make caching implementation agnostic

For version > 5.0.0.

// cache.module.ts
import { redisStore } from "cache-manager-redis-store";
import { CacheService } from "./cache.service";
import { ConfigService } from "@nestjs/config";
import { CacheModule as CacheModule_ } from "@nestjs/cache-manager";
import ...

@Global()
@Module({
  imports: [
    CacheModule_.registerAsync({
      isGlobal: true,
      inject: [
        ConfigService
      ],
      useFactory: async (configs: ConfigService) => ({
        isGlobal: true,
        max: 10_000,
        store: (): any => redisStore({
          commandsQueueMaxLength: 10_000,
          socket: {
            host: configs.getOrThrow("REDIS_HOST"),
            port: configs.getOrThrow("REDIS_PORT"),
          }
        })
      })
    })
  ],
  exports: [CacheService],
  providers: [CacheService],
})
export class CacheModule { }


// cache.service.ts
import { Cache } from 'cache-manager';
import { RedisStore } from "cache-manager-redis-store";
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Inject, Injectable } from '@nestjs/common';

@Injectable({})
export class CacheService {
  constructor(@Inject(CACHE_MANAGER) private readonly cache: Cache & RedisStore) { }

  async get<T = unknown>(key: string) {
    return this.cache.get<T>(key);
  }

  async set(key: string, value: any, seconds = 600 /* 10min */) {
    return this.cache.set(key, value, { ttl: seconds }, null);
  }

  async del(key: string) {
    return this.cache.del(key);
  }
}

Upvotes: 4

Peter Akaliro
Peter Akaliro

Reputation: 109

Follow these steps to get it working on v5

  1. Upgrade @nestjs/core, @nestjs/common and @nestjs/cli to use > 9.4.0

  2. install @nesjs/cache-manager package

  3. in your app.ts

import { CacheModule } from '@nestjs/cache-manager'; // not from "cache-manager"
  1. add this
        CacheModule.register({
            isGlobal: true,
// if you use redis
            useFactory: async () => ({
                store: redisStore as any,
                host: config.REDIS_HOST,
                port: config.REDIS_PORT,
                // ttl: 1000,
            }),
        }),

NOTE: Don't use CacheModule.resgisterAsync

Run Your app and it should work fine

Upvotes: 5

mat.twg
mat.twg

Reputation: 745

package.json

"dependencies": {
  "cache-manager": "^4.1.0",
  "cache-manager-redis-store": "^2.0.0"
}
"devDependencies": {
  "@types/cache-manager": "^4.0.1"
}

Upvotes: 6

PKS
PKS

Reputation: 773

Faced a similar issue. They have recently upgraded to a newer version. Take a look at the new docsdoc

Upvotes: 0

paul.linney
paul.linney

Reputation: 331

I came across the same error and could not figure it out either.

node-cache-manager was only updated to version 5 within the last day. https://github.com/node-cache-manager/node-cache-manager/tags

So I updated the package.json to use version 4.x

"cache-manager": "^4.0.0",

And now the caching works as expected.

Keep an eye on the package issue queue for further updates.

Upvotes: 20

Related Questions