3

In Koa, can we access the Koa Context without using the pre-bound this?

For example: this is assigned to the Koa Context:

app.use(function *(next) {
    this.url;
})

But is there something like:

app.use(function *(next, ctx) {
    ctx.url;
})

Why? Say we use an arrow function, this won't be the koa context:

app.use( function *( next ) {

    console.log( this.url ); // logs: "/"

    ( () => console.log( this.url ) )(); // logs: "undefined"

});

I know we could do:

app.use( function *( next ) {
    var ctx = this;
    ( () => console.log( ctx.url ) )(); // logs: "/"
});

and other forms of binding but I wanted to check, that by design, this is the only way.

Ross
  • 14,266
  • 12
  • 60
  • 91
  • 1
    What about using `.bind(this)`? Can that work with the fat arrow? Also, isn't the purpose of the fat arrow to preserve environment scope? Perhaps you're using it incorrectly? – Seth Mar 18 '15 at 15:40
  • why would you want to do this? – Jonathan Ong Mar 18 '15 at 16:54
  • do what? sorry don't understand the q. – Ross Mar 18 '15 at 17:25
  • 2
    Note that v2.0 provides the context as a parameter – w00t Jan 21 '16 at 12:24
  • Your premise is false. Fat arrow functions don't hijack `this`. That's one of their major feature. – geon Dec 02 '16 at 14:15
  • @geon Think you are reading between the lines. This isn't a question about arrow functions. This *was* a question Koa v1 asked ~18 months ago. – Ross Dec 03 '16 at 14:10

2 Answers2

5

Accessing this

Koa runs each middleware with this bound to a Context. Access to the request and response require going through the context, this.

This is absolutely by design. If you need to, store a reference to the context in a variable:

var self = this
//or
var ctx = this

Or use Function.prototype.bind:

myArray.forEach( function( item ){
    console.log( this.url )
}.bind( this ) )

Design of Koa

I'll paraphrase another answer and the Koa FAQ.

Express is designed to look and feel much like the "standard node way of doing things"; it follows the example set by the http module.

On the other hand, Koa is meant to replace "the node way". The author has chosen to implement his own ideal for handling requests and middleware. Koa exposes it's own versions of the request and response in this.request and this.response, keeping the original node req and res in this.req and this.res, respectively.

These examples should bring the different mindsets into focus.

The Express methodology is very action based.

app.use( function( req, res ){
    //SEND the response
    res.send( 'some text' )
})

The Koa methodology is very "fact based".

app.use( function*( next ){
    //The response IS this
    this.body = 'some text'
})

So it seems that instead of passing req and res to functions in a procedural manner, Koa exposes them as properties (or "facts") of the request.

Community
  • 1
  • 1
JoshWillik
  • 2,624
  • 21
  • 38
3

New answer:

It's now available in koa v2.

Old answer:
It is not possible. Middleware is provided to the application via thunks (single argument functions) which are provided by co.

As of writing (April 2015) thunks in co are deprecated. So Koa stays with them or moves to promises is unknown. My 2p, coming from other functional languages, thunks (and bound context) hinders expressiveness... Maybe I'm wrong, but there with arrow functions is one example

Ross
  • 14,266
  • 12
  • 60
  • 91