1

I'm trying out AdonisJS, but I'm stuck trying to get a service injected into a controller. No matter what I try, the hs constructor argument in VersionsController remains undefined.

I've also experimented with annotating the VersionController constructor with @inject(['@ioc:Service/HashService']), but with no luck. I'm not sure though if @inject is the right way for Adonis.js v5.

How do I properly inject a service class into a controller?

/providers/AppProvider.ts

    import { ApplicationContract } from '@ioc:Adonis/Core/Application'
    import HashService from 'App/Services/HashService';
    
    export default class AppProvider {
        
        protected app: ApplicationContract;
        
        constructor(app: ApplicationContract) {
            this.app = app;
        }
    
        public register() {
            this.app.container.singleton('@ioc:Service/HashService', () => {
                return new HashService();
            });
        }
    
        public async boot() {
            // IoC container is ready
        }
    
        public async ready() {
            // App is ready
        }
    
    
        public async shutdown() {
            // Cleanup, since app is going down
        }
    }

/app/Services/HashService.ts

    'use strict'
    
    export default class HashService {  
    
        async test() {}
        
    }
    
    module.exports = HashService;

app/Controllers/Http/VersionsController.ts

    import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
    import { HashService } from '@ioc:Service/HashService'
    
    export default class VersionsController {
        
        protected hs: HashService
    
        constructor(hs: HashService) {
            this.hs = hs;
            console.log("hashservice is " + hs);
        }
    
        public async get(ctx: HttpContextContract) {
            return [
                {
                    id: 1,
                    title: 'a'
                }
            ]
        }
        
        public async put(ctx: HttpContextContract) {
            return "PUT";
        }
        
    }

.adonisrc.json

    {
      "typescript": true,
      "commands": [
        "./commands",
        "@adonisjs/core/build/commands/index.js",
        "@adonisjs/repl/build/commands"
      ],
      "exceptionHandlerNamespace": "App/Exceptions/Handler",
      "aliases": {
        "App": "app",
        "Config": "config",
        "Database": "database",
        "Contracts": "contracts"
      },
      "preloads": [
        "./start/routes",
        "./start/kernel"
      ],
      "providers": [
        "./providers/AppProvider",
        "@adonisjs/core"
      ],
      "aceProviders": [
        "@adonisjs/repl"
      ]
    }
callmenikk
  • 1,358
  • 2
  • 9
  • 24
sbrattla
  • 5,274
  • 3
  • 39
  • 63

1 Answers1

5

you can use Adonisjs/fold

simply use the @inject decorator in your services;

example;

import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext";
import UserEditValidator from "App/Validators/UserEditValidator";
import UserRepository from "App/Repository/UserRepository";
import {inject} from "@adonisjs/fold";

@inject()
export default class UserService {

  constructor(private userRepository: UserRepository) {
  }

  async update(ctx: HttpContextContract) {
     //do your stuff
     
  }
}

and then in your controller;

import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext";
import UserService from "App/Service/UserService";
import {inject} from "@adonisjs/fold";

@inject()
export default class UserController {

  constructor(private userService: UserService) {

  }

  async edit({ view }){
     return view.render('user/edit', {title: 'Edit Profile'})
  }

  async update(ctx : HttpContextContract){
      await this.userService.update(ctx);

      return ctx.response.redirect().back()

  }
}
bencagri
  • 184
  • 2
  • 13