Tips on implementing mongoose 'Query<any>' types

I have been exploring ways to incorporate a cache layer into my TypeScript project. Recently, I came across an insightful article on Medium titled How to add a Redis cache layer to Mongoose in Node.js

The author demonstrates adding a caching function to mongoose.Query.prototype:

mongoose.Query.prototype.cache = function(options = { time: 60 }) {
  this.useCache = true;
  this.time = options.time;
  this.hashKey = JSON.stringify(options.key || this.mongooseCollection.name);

  return this;
};

Subsequently, within mongoose.Query.prototype.exec, the query checks if caching is enabled:

mongoose.Query.prototype.exec = async function() {
    if (!this.useCache) {
        return await exec.apply(this, arguments);
    }

    const key = JSON.stringify({
        ...this.getFilter(),
    });
    console.log(this.getFilter());
    console.log(this.hashKey);

    const cacheValue = await client.hget(this.hashKey, key);

    if (cacheValue) {
        const doc = JSON.parse(cacheValue);

        console.log("Response from Redis");
        return Array.isArray(doc)
            ? doc.map((d) => new this.model(d))
            : new this.model(doc);
    }

    const result = await exec.apply(this, arguments);
    return result;
};

To enable caching, simply call the cache() function in the mongoose query:

 books = await Book.find({ author: req.query.author }).cache();

While everything functions correctly, I encountered challenges while attempting to convert it to TypeScript. Specifically, I am uncertain about how to include type definitions for it.

The TypeScript version consistently presents errors such as:

Property 'cache' does not exist on type 'Query<any>',
Property 'useCache' does not exist on type 'Query<any>',
Property 'hashKey' does not exist on type 'Query<any>',

If anyone has suggestions on incorporating these types into 'Query', your assistance would be greatly appreciated.

Answer №1

I managed to solve the issue by following these steps. For more information, you can also refer to

Start off by creating a new file named /src/@types/mongoose.d.ts and include the code below:

type CacheOptions = {key?: string; time?: number}

declare module 'mongoose' {
  interface DocumentQuery<T, DocType extends import('mongoose').Document, QueryHelpers = {}> {
    mongooseCollection: {
      name: any
    }
    cache(options?: CacheOptions): any
    useCache: boolean
    hashKey: string
  }

  interface Query<ResultType, DocType, THelpers = {}, RawDocType = DocType> extends DocumentQuery<any, any> {}
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve a collection of nested dictionaries containing flask and angular data

In my app development journey with flask and ionic(angular), I'm working on returning a JSON list. Here's the python code snippet: def get-stocks(): # Select all stocks cursor.execute("""SELECT * FROM `tbl_symbol_index`"" ...

Using Node and Mongoose to link documents that rely on each other for reference

Is there a way to add a document after another document has been successfully inserted using node and mongoose? For example, I initiate the creation of a document with mongoose, and once it is successfully added, I want to trigger the insertion of another ...

What is the best approach for managing and obtaining accurate JSON responses when working with PHP API and AngularJS 2 services?

Encountering a backend issue with MySQL, wherein one query is producing a specific dataset: {"candidat":[{"ID":1,"nom":"Danny","prenom":"Hariot","parti":"Quamba","departement":"Ukraine","commune":"Chapayeve"},{"ID":2,"nom":"Shari","prenom":"Adamkiewicz"," ...

Tips on inferring a distinct generic type for every element within an array of objects

I'm working on code that creates a timeline chart for data. I want the code to accept an array of series, each containing data and various getters used to position and render the data on the chart. Below is a simplified example of the code. The actua ...

Is there a way to display an array of data in separate mat-form-field components?

I am dealing with an array that stores 4 data points: [onHour, onMinute, offHour, offMinute]. I also have 4 elements that are not in an array and need to be repeated. <div class="on"> <mat-form-field appeara ...

Continuous Updates to innerHtml in Angular2

While working on a project, I encountered an issue that seems to be more about style than anything else. The endpoint I am calling is returning an SVG image instead of the expected jpeg or png format, and I need to display it on the page. To address this, ...

Guide to turning off the previous button in FullCalendar using Angular 7 and TypeScript

Can someone help me with disabling the previous button on FullCalendar if I go back 2 months? For example, if it's currently April and I navigate to February, I want the previous button to be disabled. I have FullCalendar implemented, but all the sol ...

Creating a Loader while navigating routes in Next 13: A step-by-step guide

During the navigation to Next 13, I want to display a loading indicator on my screen to inform the user about the ongoing navigation process. I attempted to implement this using the traditional method, but I encountered difficulties as I cannot utilize ne ...

Nestjs opts to handle invalid routes by throwing a NotFoundException rather than a MethodNotAllowed

I've recently developed a Rest API using NestJS and now I'm focusing on customizing error responses. Specifically, I want to address the scenario where a user calls an endpoint with the incorrect HTTP method. Take for instance the endpoint GET / ...

calculating the dynamic height of a document from top to bottom using Angular

Is there a way to dynamically calculate the height of each page from top to bottom in Angular? The syntax that works in JavaScript seems to give an error in Angular. console.log( (document.height !== undefined) ? document.height : document.body.offsetHeigh ...

Encountered a problem with AngularUniversal prerendering: UnhandledPromiseRejectionWarning: Unable to locate NgModule metadata for 'class{}'

Objective The task may seem lengthy, but it's straightforward! Currently, I am utilizing Angular Universal for Server-Side Rendering (SSR) by following a tutorial. The Universal/express-engine has been installed, main.js is generated in the dist/pro ...

Angular2 form builder generating dynamic forms based on results of asynchronous calls

When creating my form, I encountered a challenge with passing the results of an asynchronous call to the form builder. This is what I have attempted: export class PerformInspectionPage implements OnInit { checklists: any; inspectionform: FormGroup; n ...

Challenges with utilizing Ionic Native in a cross-platform application

I am currently developing an application using Ionic 2 that can function both as a website in a browser and as a mobile app on iOS and Android. One key aspect of the app is its use of the SQLite plugin when accessed on mobile devices. However, I have encou ...

Angular 7 navigation successfully updates the URL, but fails to load the corresponding component

Despite exhausting all other options, I am still facing a persistent issue: when trying to navigate to a different component, the URL changes but the destination component fails to load. Explanation: Upon entering the App, the user is directed to either ...

Managing relationships within TypeORM's single table inheritance using a base class for targeting relations

In my application, I aim to provide users with notifications in the form of news items of various types. The relationship between User and NewsItem needs to be one-to-many, with NewsItem serving as a base class for different types of news items. Below is ...

Encountering [Object] error in Angular's ngbTypeahead functionality

Here is the code for my input field in component.html: <input type="text" class="form-control" [(ngModel)]="searchQuery" [ngbTypeahead]="recommends" name="searchQuery" typeaheadOptionField="user ...

I am unable to access the object property in Typescript

Here is an object definition: const parsers = { belgianMobile: (input: string) => input.replace(/^(0032|0)(\d{3})(\d{2})(\d{2})(\d{2})/, '$1$2 $3 $4 $5').replace('0032', '+ 32 '), }; Now, I want ...

Ways to ensure that when changes occur in one component, another component is also updated

How can I update the cart badge value in the navbar component every time a user clicks the "Add to Cart" button in the product-list component? The navbar component contains a cart button with a badge displaying the number of products added to the cart. n ...

The young one emerges within the SecurePath component temporarily

Setting up authorization in React has been a priority for me. Ensuring that users cannot access unauthorized pages within the application is crucial. To achieve this, I have created a custom component as shown below. import { ReactNode } from "react&q ...

Data is not being stored in the MongoDB Model/Schema as expected

I'm encountering an issue with my MongoDB database. It appears to not be receiving the data I am attempting to send to it, resulting in an empty database despite everything else functioning smoothly. The application I'm working on involves scrap ...