Hello, I'm begginer in nodejs and especially generators app so i don't know how to do this on my own. In Google there is a lack of information:
twitch.getAuthenticatedUserChannel(body.access_token, collectInformation);
function collectInformation(err, body) {
if(err) {
console.dir(err);
} else {
HomeController.prototype._user = {
twitch_id: body._id,
username: body.name,
display_name: body.display_name,
logo: body.logo
};
}
}
I want to yield information about user to session but i can't do this in collectInformation because there is an error of can't use yield in function (i think so).
Second question is: How can bind other HomeController function to callback for ex.
* logged(request, response) {
[...]
twitch.getAuthenticatedUserChannel(body.access_token, collectInformation); //instead of collectInfromation() how can i bind finish() presented below?
* finish() {
console.log(HomeController.prototype._user);
}
Hi @Perfect7M
I add the sample problem as you, the solution here is the promises (they can be yielded).
You should try to transform your method to a Promise, for this, I use https://github.com/digitaldesignlabs/es6-promisify and it works well for me:
const promisify = require('es6-promisify');
cont getAuthenticatedUserChannel = promisify(twitch.getAuthenticatedUserChannel);
// So now you can use yield
const res = yield getAuthenticatedUserChannel(body.access_token)
// Here you can use res.name, res._id, etc...
I'm not sure it's a good idea to set: HomeController.prototype._user = { ... }
You should use the context directly: this._user = { ... }
And them you can access it directly inside your controller.
I hope it helps you to understand the generators a bit better 馃槃
Yes i tried to use Promise but when i get error message that 'callbacks can't be made promise'.
Can't do this like above because this plugin https://www.npmjs.com/package/twitch-api make use of callbacks and you must provide callback for every use of its function but callbacks can't be promise and there is a problem.
Thanks for example, I use it for sure :)
Can you try my example and tell me if it's working?
es6-promisify module will handle the callback for you don't worry
Cannot read property 'clientId' of undefined
const twitch = new TwitchAPI({
clientId: Config.get('twitch.client_id'),
clientSecret: Config.get('twitch.client_secret'),
redirectUri: Config.get('twitch.redirect_uri'),
scopes: Config.get('twitch.scopes')
});
const code = request.get().code;
console.log(twitch);
const getToken = Promisify(twitch.getAccessToken);
const res = yield getToken(code);
console.log(res);
First i must obtain access_token co i must send code from get... but its not working. When i do console.log(twitch); evrything is setted up.
I found the bug @Perfect7M
It's because twitch-api use an instance and the getAccessToken method is from the prototype, so you just have to bind the twitch.getAccessToken:
const getToken = Promisify(twitch.getAccessToken.bind(twitch));
Voil脿 馃槃
Great it worked 馃槃 I am closing the issue, please feel free to report any issues/bugs
Hello @Atinux, @Perfect7M
I am using this npm package https://www.npmjs.com/package/node-twitter-api
from your above reference used es6-pomisify with following code
const getToken = promisify(twitter.getRequestToken.bind(twitter), {multiArgs: true})
getToken().then(function (result) {
console.log(result) // Is valid checked ok
yield request.session.put({'requestToken' : result[0], 'requestTokenSecret' : result[1]})
});
Again got error at yield ing request.session
Please guide next.
Thanks
@navdeepsingh
const getToken = promisify(twitter.getRequestToken.bind(twitter), {multiArgs: true});
const result = yield getToken();
yield request.session.put({'requestToken' : result[0], 'requestTokenSecret' : result[1]})
These should work for u..
But i would reccomend u to take classes for generators..
@muxahuk
I tried.. but got following err
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
please explain about classes for generators to use.
thks!!
Can you provide us you code example?
@navdeepsingh
These error is related to you'r api, not to these code particular ( if it works with promise - it should work with yield )
these code should be same as:
return getToken().then(function (result) {
console.log(result) // Is valid checked ok
return request.session.put({'requestToken' : result[0], 'requestTokenSecret' : result[1]})
}).then( function() {
console.log( 'session should be set here' );
return response.send( 'something' );
} );
If these code doesn't works than u have problem not with yield..
@muxahuk
const getToken = promisify(twitter.getRequestToken.bind(twitter), {multiArgs: true})
return getToken().then(function (result) {
return {'requestToken' : result[0], 'requestTokenSecret' : result[1]}
}).then( function(tokens) {
console.log( tokens )
yield request.session.put( tokens )
return response.send( 'https://twitter.com/oauth/authenticate?oauth_token=' + tokens.requestToken );
} );
Final code. But still yield of storing values in session not works. :(
@navdeepsingh
const getToken = promisify(twitter.getRequestToken.bind(twitter), {multiArgs: true})
const tokens = yield (getToken()
.then(function(result) {
return {
'requestToken' : result[0],
'requestTokenSecret' : result[1]
}
}))
yield request.session.put(tokens)
response.send('https://twitter.com/oauth/authenticate?oauth_token=' + tokens.requestToken)
Try this
Or this:
const getToken = promisify(twitter.getRequestToken.bind(twitter), {multiArgs: true})
const tokens = yield getToken()
yield request.session.put({ requestToken : tokens[0], requestTokenSecret : tokens[1] })
return response.send( 'https://twitter.com/oauth/authenticate?oauth_token=' + request.session.requestToken )
@navdeepsingh
you still don't get it.. u CAN'T write yield in function(){} only in function *(){} ( generator ).
the difference between promise and generator is that in promise u have to chain you'r async calls with .then, but in generator u have to write yield before async function..
so if we have async function test
// promise:
return test().then( result => {
// do something with result
} );
// generator:
const result = yield test();
// do something with result
//so, for multiple calls it would be like so:
// primise:
return test().then( result => {
//do something with result
return test2(); // return enother async call
}).then( result2 => {
// do something with result2 witch is beeing return from test2 function
} );
generators:
const result = yield test();
// do something with result
const result2 = yield test2();
// do something with result2
So you'r mistake is writing yield inside promise
.then( function(tokens) {
console.log( tokens )
**yield request.session.put( tokens )**
return response.send( 'https://twitter.com/oauth/authenticate?oauth_token=' + tokens.requestToken );
} );
u need to return as with test2 function request.session.put function
so these should work:
const getToken = promisify(twitter.getRequestToken.bind(twitter), {multiArgs: true});
const sessionPut = promisify( request.session.put.bind( request.session ) );
return getToken().then(function (result) {
return {'requestToken' : result[0], 'requestTokenSecret' : result[1]}
}).then( function(tokens) {
console.log( tokens )
return sessionPut( tokens )
.then( () => tokens );
} )
.then( function( tokens ) {return response.send( 'https://twitter.com/oauth/authenticate?oauth_token=' + tokens.requestToken ); } ) ;
@Atinux It prompts Error: Cant set headers after they are sent.
@muxahuk thanks for explaining in simple words to me.. I got overview now.
but promisifying request.session.put not seems work as it stucks at
return sessionPut( tokens )
.then( () => tokens );
I tried to work on this issue, yet not success.
@navdeepsingh try addong .catch at the end of the line to catch any error occured during promisses..
@muxahuk You cannot promisify the request.session.put method (see https://github.com/adonisjs/adonis-framework/blob/develop/src/Session/index.js#L212)
@navdeepsingh do you mind sharing the code of you Adonis controller? You might call response.send somewhere else before the promise is resolved.
@muxahuk
tried that too
https://gist.github.com/navdeepsingh/46fe7061cd5e9a7eb1d243f9a07892d6
but no response still.
@navdeepsingh I would suggest you to understand ES2015 generators.
TIP: You can simply yield promises instead of chaining then. Below should work
const getToken = promisify(twitter.getRequestToken.bind( twitter ), {multiArgs: true})
const result = yield getToken()
yield request.session.put('requestToken', result[0])
yield request.session.put('requestTokenSecret', result[1])
response.send(`https://twitter.com/oauth/authenticate?oauth_token=${tokens.requestToken}`)
@thetutlage i will continue my study for ES2015 features.
I tried above code of yield promises, again the same error of
Error: Can't set headers after they are sent.
Here is my code
https://gist.github.com/navdeepsingh/e57893a4fe5f26016fef86344bffe78c
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.