o..o
o..o

Reputation: 1921

Opening Mongoose connection in AdonisJS provider times out

I was following this article to use Mongo in AdonisJS 5 project.
I have an AdonisJS provider which I have created by node ace make:provider Mongo (it is registered in .adonisrc.json):

import { ApplicationContract } from '@ioc:Adonis/Core/Application'
import { Mongoose } from 'mongoose'

export default class MongoProvider {
  constructor(protected app: ApplicationContract) {}

  public async register() {
    // Register your own bindings
    const mongoose = new Mongoose()

    // Connect the instance to DB
    await mongoose.connect('mongodb://docker_mongo:27017/mydb')

    // Attach it to IOC container as singleton
    this.app.container.singleton('Mongoose', () => mongoose)
  }

  public async boot() {
    // All bindings are ready, feel free to use them
  }

  public async ready() {
    // App is ready
  }

  public async shutdown() {
    // Cleanup, since app is going down
    // Going to take the Mongoose singleton from container
    // and call disconnect() on it
    // which tells Mongoose to gracefully disconnect from MongoBD server
    await this.app.container.use('Mongoose').disconnect()
  }
}

My model is:

import { Schema, model } from '@ioc:Mongoose'

// Document interface
interface User {
  email: string
}

// Schema
export default model(
  'User',
  new Schema<User>({
    email: String,
  })
)

Controller:

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'

export default class UsersController {
  public async index({}: HttpContextContract) {
    // Create a cat with random name
    const cat = new User({
      email: Math.random().toString(36).substring(7),
    })
    // Save cat to DB
    await cat.save()

    // Return list of all saved cats
    const cats = await User.find()

    // Return all the cats (including the new one)
    return cats
  }
}

And it is timeouting.
It is working, when I open the connection in controller like this though:

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'
import mongoose from 'mongoose'

export default class UsersController {
  public async index({}: HttpContextContract) {
    await mongoose.connect('mongodb://docker_mongo:27017/mydb')

    // Create a cat with random name
    const cat = new User({
      email: Math.random().toString(36).substring(7),
    })
    // Save cat to DB
    await cat.save()

    // Return list of all saved cats
    const cats = await User.find()

    // Close the connection
    await mongoose.connection.close()

    // Return all the cats (including the new one)
    return cats
  }
}

I have just created an AdonisJS provider, registered it in .adonisrc.json, created a contracts/Mongoose.ts with typings, and use the model in controller.

Any idea? I'm stuck for a day with this.
Thanks

Upvotes: 1

Views: 1113

Answers (3)

Gul mehar
Gul mehar

Reputation: 1

I followed this article too, and I have the same issue you discussed. but resolved this by importing mongoose in my model a little differently. import mongoose in the model like this import Mongoose, { Schema } from '@ioc:Mongoose' instead of import { Schema, model } from '@ioc:Mongoose'

Example:

import Mongoose, { Schema } from '@ioc:Mongoose'

 // Document interface
  interface User {
    email: string
  }

 // Schema
 export default model(
 'User',
  new Schema<User>({
  email: String,
 })
)

Upvotes: 0

Alexandre
Alexandre

Reputation: 46

I managed to resolve this issue by not storing mongoose in a variable. It seems the mongoose variable you declare in your MongoProvider is the root of your timeout error.

So I did as follow :

export default class MongoProvider {
      constructor(protected app: ApplicationContract) {}
    
      public async register() {
        await mongoose.connect('mongodb://localhost:27017/dbName')
    
        this.app.container.singleton('Mongoose', () => mongoose)
      }
    
      public async boot() {
        // All bindings are ready, feel free to use them
      }
    
      public async ready() {
        // App is ready
      }
    
      public async shutdown() {
        await this.app.container.use('Mongoose').disconnect()
      }
}

Upvotes: 3

o..o
o..o

Reputation: 1921

If someone would be interested:

with the help of the article author the reason why it is not working was missing Mongoose when creating the model (Mongoose.model instead of just model:

export default Mongoose.model(
  'User',
  new Schema<User>({
    email: String,
  })
)

Upvotes: 0

Related Questions