Easy question. Just an explict look:
var token = "12345"
function einloggen(){
var test = particle.login({username: userName, password: passWord});
test.then(
function (data) {
token = data.body.access_token;
console.log('tokenoutprint1:', token);
},
function (err) {
console.log('LoggingIn Failed', err);
}
);
console.log('tokenoutprint2:', token);
}
einloggen();
after that i want to reuse the "new" token in a different Function...
callFunctionAVC(token);
The third last line will print me 12345. But I want print out the "new" token, defined in. Like in "normal" java
I don't know why because the first console.log shows me the right token.
SO HOW DO I GET THE "TOKEN" TO A GLOBAL VARIABLE. Thats my "real" Question. Please send full codes only otherwise i won't get it.
Sorry for not being a pro, I'm just learning in school.
Greetings.
The einloggen function is not (visibly) being called before the console.log, which means you set token = "12345", console.log() it and some time later you may or may not call the einloggen function.
I think what you wanted to do is:
function einloggen() {
//your code
}
einloggen(); // Execute the method
console.log(token);
There's a possibility this won't work as expected as well because you're using Promises in your einloggen function.
You could also try to execute console.log(token) from the developer console of your browser.
Related
I am using AWS Cognito to authenticate users in a new app that I am building.
I am using the amazon-cognito-identity-js library in my project (link to Github: https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js). Since users in this particular user pool cannot sign themselves up - I sign them up manually - I know that I need "Use case 23" as stated in the README.md from Github.
So my code is as follows:
...
const userPoolData = {
UserPoolId: <MY_USER_POOL_ID>,
ClientId: <MY_CLIENT_ID>
};
const userPool = new CognitoUserPool(userPoolData);
const authenticationData = {
Username: email,
Password: tempPassword
};
const userData = {
Username: email,
Pool: userPool
}
const authenticationDetails = new AuthenticationDetails(authenticationData);
const cognitoUser = new CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
console.log(result);
},
onFailure: (err) => {
console.log("Error from cognito auth: ", err);
},
newPasswordRequired: (userAttributes) => {
delete userAttributes.email_verified;
cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
}
})
...
When I execute this code, I successfully confirm my user. I can see this in the AWS Cognito console. However, instead of receiving the result object, I get an error in the javascript console on the client that says:
Uncaught (in promise) TypeError: Cannot read property 'onFailure' of undefined
at eval (CognitoUser.js:572)
at eval (Client.js:108)
But when I attempt to sign in with the newPassword in place of the tempPassword previously sent, I am now able to successfully get the resultobject with the three tokens all present.
So I know that everything is kinda working, but isn't what I am expecting.
What is causing this error? How can I fix it? I want to receive the result object immediately when the user first signs in with the tempPassword and their newPassword so that they can start using the app.
EDIT:
Thinking that I had to retrieve the userAttributes myself was a mistake. The newPasswordRequired function passes them automatically. So I updated my code above to go with "Use case 23" as presented on Github.
But now I get a slightly different error than before:
Uncaught (in promise) TypeError: callback.onFailure is not a function
at eval (CognitoUser.js:572)
at eval (Client.js:108)
Everything still works as far as Cognito is concerned, but there must be something wrong with my onFailure function, which is very strange.
Any thoughts?
Thanks in advance
Alright, I solved it. The issue was that I was using ES6 arrow functions. As Apolozeus pointed out, I needed to pass this into the cognitoUser.completeNewPasswordChallenge function. But due to the way ES6 behaves, this was returning undefined. So, changing my cognitoUser.authenticateUser function to the following solved everything:
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
resolve(result.getAccessToken().getJwtToken());
},
onFailure: function (err) {
console.log("Error from cognito promise: ", err);
reject(err);
},
newPasswordRequired: function (userAttributes) {
delete userAttributes.email_verified;
cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
}
})
I'm going to play around with the amazon-cognito-identity-js library a bit and see if I can get ES6 arrow functions to work here. It's really annoying to have to work around that.
Shout out to Apolozeus for the help
Please update the line cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes); into cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this) Basically, this will make sure the callback function within the same object.
I am currently using Chakram API Testing framework to test some REST API endpoints.
The first API gets a CSRF token which is used in the rest of the endpoints in the headers.
The CSRF API returns a JSON object - something like this
{
csrf_token : Aajkndaknsda99/adjaj29adja
}
This is how I'm doing it right now
describe('Hits the CSRF API to get the token',()=>{
let csrf_tok;
before(()=>{
return chakram.wait(response = chakram.get(API_ENDPOINT,headers));
});
it('gets the csrf token from the response',()=>{
return response.then(function(resp){
csrf_tok = response.body.csrf_token;
console.log(csrf_tok) //works fine and I can see the value correctly
exports.csrf = csrf_tok;
});
});
});
In my other file, where I need to use the CSRF token, I'm doing something like this
var token = require('../test/csrf_token');
var options ={
headers :{
//other headers
CSRF-TOKEN : token.csrf;
}
}
However, this is not working and the rest of the API endpoint tests are failing due to the token being passed as undefined. I hard coded the value of token and then the tests starts working. However, I do not want to do this every time (I plan on deploying this as a part of pipelines).
This issue seems to be that the variable cannot be accessed outside of Mocha's describe context. Is that right? If so, how can I overcome it?
You can declare the variable outside describe and then export it from outside 'describe'.
Other thing I have noticed regarding line:
csrf_tok = response.body.csrf_token;
It should be :
csrf_tok = resp.response.body.csrf_token;
This doesnt answer your specific question, but I needed something similar - where I needed to get an auth token that could then be passed to other tests.
I did this with a before hook in a shared.js file
before ( function getToken (done) {
chai.request(host)
.post(tokenURL)
.send({my params})
.end(function(err, response){
... getToken expectations
this.myToken = response.token;
done();
});
});
Then in test.js file you can just use 'myToken', as long as your shared.js file is in the root test dir
See https://gist.github.com/icirellik/b9968abcecbb9e88dfb2
I have to call 2 external api's, 2nd one is interdependent on the result of first one, i am not sure whether its better to call it Synch way or async way. I am also dumping the data to db, note that this function is called in the server and runs independent of client. This method runs at regular intervals. Below is my code. Can anybody please suggest me to do this in better way ?
getUser: function(){
console.log('getMultipleDeviceLocation');
this.unblock();
var arrayOfResponse = [];
try{
var userData = HTTP.call("GET", "url");
if(userData && !userData.error){
var userResult = userData.data;
var userDateTime = new Date();
for(key in result){
NetworkUsers.insert({
'dateTime': userDateTime,
'userid': userResult[key].userid,
'userName': userResult[key].userName
});
try{
var response = HTTP.call("GET","url"+result[key].userid);
if(response){
var result = response.data;
var dateTime = new Date();
DeviceView.insert({
'dateTime' : dateTime,
'nearAPs' : result.nearByAPs || '',
'userid' : result.userid,
'userName': result.userName
});
}
}catch(error){
console.log(error);
}
}
}else{
console.log('error');
}
}catch(error){
//Main Try Catch Block
console.log(error);
}
}
What i want here is once the first call is done and it returns a response i want those data to be dumped to the db and using the same data i want to make one more all call. Will async create problem here ? do i have to make it sync ?
Well, your actually doing sync HTTP call, which would usually work without any trouble.
I hope you just wrote "url" string to second param because you do not want to show what you're calling on ST. If not, you probably misunderstand something, you have to write the url adress of your api here.
var userData = HTTP.call("GET", "url");
#Julien Leray You mean to say, what i have written will work fine ?
You make me laught on this one; don't you test what your doing?
I dunno the API your trying to reach (like I said before, I hope you're just hidding it!). I don't know if it's work, but the concept should. You don't have anything crazy here, every call are sync, you shouldn't have any trouble.
Now, for going further, you could make it async. I propose you on commentary the Meteor.WrapAsync if you wanted to test pretty sweet Meteor features, but you could also make it vanilla, just by callback.
Eg Meteor.WrapAsync:
//dont want to show up my real Api Adress, using fake one
var url = "http://myApiUrl/foo/bar";
var options = {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}};
var getToSync = Meteor.wrapAsync(HTTP.get);
var data = getToSync(url, options);
//sweet, you can use data as if it was sync!
Do I well answered to your question or you're missing something?
I am trying to build a simple background job on the Parse Cloud. Right now, I'm just testing, but I am having a problem when performing a query.
If I comment out:
//query.ascending("createdAt");
the console log shows all the messages and no errors. If I don't comment it out, I get an error. Can anybody explain why this is happening? Is it an authentication error?
Parse.Cloud.job("cleanPosts", function(request, status) {
var Post = Parse.Object.extend("Post");
var query = new Parse.Query(Post);
query.ascending("createdAt");
query.each(function(post) {
console.log( "objectId:" + post.get("message") );
}).then(function() {
status.success("Success");
}, function(error) {
status.error();
});
});
When using Parse.Query.each, you do not need to (and cannot) provide an orderBy. It will run the callback for every object (actually ordered by objectId).
The official error is "Cannot iterate on a query with sort, skip, or limit." and it should appear if you log that in the error block.
So I am using a function as such to get the access token of the already authenticated user that is currently on my website:
var token;
FB.getLoginStatus(
function(response){
if (response.session) {
alert(response.session.access_token);
//This correctly shows the access token. <-----GOOD
token = response.session.access_token;
}
else{
//Other stuff.
}
}
);
alert(token);
//This shows undefined. <------PROBLEM
The only way to know the access token it seems is to be within the anonymous function called within the call to FB.getLoginStatus.
I have determined that the problem is that the anonymous function inside of FB.getLoginStatus is not executed until the end of all other scripts on the page. Therefore, the variable "token" will not be set until everything is done executing, rendering it useless.
Is there a way then to extract the access token into a universally accessible variable? I don't want to have to write all my code which requires knowledge of the access token in a single anonymous function.
Ye the issue is that the getLoginStatus is an asynchronous call that connects to the FB api. But in the meanwhile your script continues running and so the alert(token); gets called before the getLoginStatus() finished. So the token is not set yet.
I don't know what you want to do exactly with the token, but my way to do this would be to call a function inside the getLoginStatus() as soon as the token has been loaded, and then proceed with the functionality you want. So...
var token;
FB.getLoginStatus(
function(response){
if (response.session) {
alert(response.session.access_token);
//This correctly shows the access token. <-----GOOD
token = response.session.access_token;
continueScript();
}
else{
//Other stuff.
}
}
);
function continueScript() {
....
doSomeMoreFunctionalitiesWithToken();
....
}
function doSomeMoreFunctionalitiesWithToken() {
alert(token);
}
You could for example just show a "loading..." indicator on the screen and only remove it and show the actual content after the getLoginStatus() finished its task and thus after the token has been set.
Hope this helps you.
Try using the expression FB._session.access_token to get the access token from any other location.