Reputation: 540
I probably don't understand something about JS, but I'm having an issue writing Purest response to the page body. Like here:
var koa = require('koa')
, session = require('koa-session')
, mount = require('koa-mount')
, koaqs = require('koa-qs')
, accesslog = require('koa-accesslog')
, router = require('koa-router')()
, app = koa();
var Grant = require('grant-koa')
, grant = new Grant(require('./config.json'))
app.keys = ['grant']
app.use(accesslog())
.use(session(app))
.use(mount(grant))
.use(router.routes())
.use(router.allowedMethods());
koaqs(app)
router.get('/handle_facebook_callback', function *(next) {
getProfile(this.query.access_token);
})
var config = {
"facebook": {
"https://graph.facebook.com": {
"__domain": {
"auth": {
"auth": {"bearer": "[0]"}
}
},
"{endpoint}": {
"__path": {
"alias": "__default"
}
}
}
}
}
var request = require('request')
, purest = require('purest')({request})
, facebook = purest({provider: 'facebook', config})
function getProfile(access_token, responseToBody){
facebook.get('me')
.auth(access_token)
.request(function (err, res, body) {
this.body=JSON.stringify(body,null,2);
})
}
if (!module.parent) app.listen(3000);
console.log('oh!GG is running on http://localhost:3000/');
I would assume in facebook.request function "this.body=JSON.stringify(body,null,2);" part should write the response into the body, however it doesn't. What exactly is the issue here?
Upvotes: 0
Views: 204
Reputation: 9454
The route (a generator) isn't waiting for getProfile
to finish. You need yield
.
Right now in your snippet, it executes getProfile
, which returns immediately to the generator, the generator finishes, Koa sees that you haven't set this.body
, so it defaults to a 404 response.
Once the callback in getProfile
finally fires at some later point, the response has already been sent and you get the error.
The general solution for getting a callback-style function to work with Koa (i.e. making it so you can yield
it) is to wrap it in a Promise:
function getProfile (access_token) {
return new Promise(function (resolve, reject) {
facebook.get('me')
.auth(access_token)
.request(function (err, res, body) {
if (err) return reject(err)
resolve(body)
})
})
}
router.get('/handle_facebook_callback', function * (next) {
const profile = yield getProfile(this.query.access_token)
this.type = 'application/json'
this.body = JSON.stringify(profile, null, 2)
})
getProfile
now returns a Promise which you can yield.
Also, notice that I changed it so that getProfile
resolves with the profile object, and the Koa handler is the one that stitches together this.body
and the JSON.
This is generally how you want to do things in Koa so that all of your response mutation happens inside the handler in one place.
Upvotes: 3