0

How do we access koa js route context (this) and es6 class this within a es6 class?

When i try to access class property using this.name i get undefined

test.js

export default class {
  constructor (opts) {
    this.name = 'test'
  }

  welcome () {
    console.log(this.name) // 'this' is UNDEFINED. Trying to access class property. But getting undefined
    this.body = 'welcome '+this.params.name // 'this' works fine here as a koa reference
  }
}

app.js

import test from './test'
let Test = new test({})

router.get('/test/:name', Test.welcome)
sravis
  • 3,562
  • 6
  • 36
  • 73
  • 2
    Context is lost when you passing callback as parameter like `Test.welcome`. Just use `() => Test.welcome()` instead. – Andrey Oct 18 '16 at 13:36
  • 1
    Your capitalisation is odd. Classes should be uppercase, instances lowercase. – Bergi Oct 18 '16 at 13:39
  • Use `router.get('/test/:name', function() { Test.welcome(this) })` and add a `context` parameter to your method – Bergi Oct 18 '16 at 13:41
  • @Bergi router.get('/test/:name', function () { Test.welcome(this) }) this work perfectly. But using es6 fat arrow give 'this' as undefined router.get('/test/:name', () => { Test.welcome(this) } ) any idea? This is not my actual code. I have better casing in actual code :-) – sravis Oct 19 '16 at 03:49
  • @sravis Yes, [that's expected](http://stackoverflow.com/q/34361379/1048572). Though I can't really believe that koa routers rely on the `this` keyword – Bergi Oct 19 '16 at 04:26
  • Koa itself uses `this` in its middleware for the first version. Koa v2 uses `async` arrow functions with `ctx` passed to the arrow function as the first argument. Even if you're not using Koa 2 with `async` (which requires `babel`), I believe you can just do something like this currently: `router.get('/', (ctx) => { ... });` – Saad Oct 19 '16 at 06:12
  • @Andrey you save my life :D – Vui Dang Mar 06 '19 at 07:35

1 Answers1

-1

I'm not sure about the class declaration and export syntax you're using and I'm thinking that might be the issue.

Something like this should work (note that this code works with require but it should be just the same with import):

test.js

class test{
    constructor(opts) {
        this.name = 'test';
    }

    welcome() {
        console.log(this.name); // 'this' is UNDEFINED. Trying to access class property. But getting undefined
        this.body = 'welcome ' + this.params.name; // 'this' works fine here as a koa reference
    }
}

module.exports = test;

app.js

let test = require('./test');
let Test = new test({});

Test.welcome();

While this code shows this.name perfectly fine, it breaks on this.params, which I assume you have declared elsewhere.

Brady Dowling
  • 4,920
  • 3
  • 32
  • 62