Playing Next Lesson In
seconds

Let's Learn AdonisJS 6 #2.10

Cleaning Up Routes with Controllers

In This Lesson

We'll learn what controllers are and how they can be used to drastically simplify our route definitions by allowing us to move our route handlers off the route definition and into the controller.

Created by
@tomgobich
Published

Join the Discussion 10 comments

Create a free account to join in on the discussion
  1. @Jean

    Hi,

    When I save routes.ts file, imports remain identical. Do we have to do anything to make it work?

    1
    1. Responding to Jean
      @tomgobich

      Hi Jean!

      The standard import for controllers will work just fine, for example

      import MoviesController from '#controllers/movies_controller'
      Copied!

      However, mine changed to lazy style imports on save within the video due to the ESLint I set up and configured code actions for within VS Code in lesson 1.4 of this series.

      Below is an example of the ESLint rule error that's auto-fixed by my code action configuration when I save my routes.ts file.

      ESLint is completely optional! It essentially is a style guide for your code, and anything not matching the style guide will display an ESLint error.

      If you'd like to use it, you can install the ESLint extension within VS Code. Then, you can have it auto-fix ESLint errors by adding the below within your VS Code settings.json

      "editor.codeActionsOnSave": {
        "source.fixAll.eslint": "explicit"
      } 
      Copied!
      1
      1. Responding to tomgobich
        @Jean

        For mystical reasons, I missed that part. Sorry :D

        By the way, the new version of Adocasts is cool.

        1
        1. Responding to Jean
          @tomgobich

          No worries at all, Jean!! :D

          Thank you, I really appreciate that!!

          0
  2. @frp

    Hi Tom!

    I'm trying to inject the context into a controller, and it is not working:

    import type { HttpContext } from '@adonisjs/core/http'
    import { inject } from '@adonisjs/core'
    
    @inject()
    export default class JoinController {
      ctx: HttpContext
    
      constructor(ctx: HttpContext) {
        this.ctx = ctx
      }
    }

    I got this error message:

    Cannot inject "[Function: Object]" in "[class JoinController]

    Sorry about the massive font lol. It looks like in the docs but does not work. Any ideas?

    1
    1. Responding to frp
      @tomgobich

      Hey frp! When a route calls a controller's method as its handler the HttpContext is automatically provided as their first parameter, so you shouldn't need to inject the context into a controller.

      That said, somewhere Harminder Virk explained this well, but I can't seem to find it. The error though is because the HttpContext can't be bound in this context. If you were to bind it to a service, and then bind the service to your controller, all would work.

      export default class MoviesController {
        async index(ctx: HttpContext) { // <--
          return ctx.view.render('pages/home')
        }
      }
      Copied!

      Here's an example of binding the HttpContext to a service and then the service to a controller.

      
      import { HttpContext } from '@adonisjs/core/http'
      import { inject } from '@adonisjs/core'
      
      @inject()
      export default class MovieService {
        constructor(public ctx: HttpContext) {}
      }
      Copied!
      • app
      • services
      • movie_service.ts
      
      import type { HttpContext } from '@adonisjs/core/http'
      import Movie from '#models/movie'
      import { inject } from '@adonisjs/core'
      import MovieService from '../services/movie_service.js'
      
      @inject()
      export default class MoviesController {
        constructor(protected movieService: MovieService) {}
      
        async index({ request, view }: HttpContext) {
          console.log(request.url())
          console.log(this.movieService.ctx.request.url())
          return view.render('pages/home')
        }
      }
      Copied!
      • app
      • controllers
      • movies_controller.ts
      0
      1. Responding to tomgobich
        @frp

        Ok thanks. That might do what I want just as well.

        0
        1. Responding to frp
          @tomgobich

          Anytime! Yeah, most of the time, I like to offload most of my business logic into services, keeping controllers clean to just handle the request flow.

          0
  3. Hello Master.

    When I try to make a request via the api, the message "Connection was refused by the server." is being returned.

    I changed the origin to '*'(config/cors.ts), but unfortunately I was unsuccessful.

    Access via http (brownser) works perfectly, but via rest api does not.

    0
    1. Responding to gabriel-moraes
      @tomgobich

      Hi Gabriel! Unfortunately, there isn't a straightforward answer here with the given information. Are your API requests being sent from inside your application or via a REST client? It sounds like your application works a-okay, your environment is just having issues connecting to it. This could be due to firewall settings or even WSL vs Non-WSL, if you're on Windows. Or, you may just need to use 0.0.0.0 instead of localhost if you're using a REST client.

      0