Variable not getting set from within function - javascript

I come from a Python background and have very little JavaScript experience, so I'm a little bit out of my element here.
I'm trying to do something seemingly simple, get an AWS account ID and store it in a variable. I'm referencing the code from this StackOverflow question but I've modified it a bit.
var account = sts.getCallerIdentity({}, function (err, data) {
if (err) {
console.log("Error ", err)
} else {
account = data.Account.toString();
console.log(account);
return account
}
});
//console.log(account);
If I leave the console.log statement commented out, I see the AWS account ID being printed to the console, which is what I'm expecting. However, if I uncomment the line, I get a very big object (which I assume is actually the data variable) that is being printed to the console.
I just want the account variable to be equal to the account ID. What am I doing wrong here?

The function is async so you cant really assign the value. The value gets resolved in the callback at some time in the future. By this point the console.log has already executed.
You can do 2 things, add your logic that requires account in the callback or use promises.
sts.getCallerIdentity({}).promise().then((data) => console.log(data));
sts.getCallerIdentity({}, (err, data) => {...stuff});
Remember these values are resolved sometime in the future.

The account variable won't get set with the data you need until the callback is run. Perhaps try something like this?
var account = sts.getCallerIdentity({}, function (err, data) {
if (err) {
console.log("Error ", err)
} else {
account = data.Account.toString();
doOtherStuff();
}
});
function doOtherStuff() {
console.log(account);
}

Related

Javascript async function gets correct data from API, but only returns "undefined"

I looked a bit on the web and couldn't find a good answer to my question, so I'll ask it to you guys.
I have an async function, that gets true/false data from an API, I am able to print the value that I got from the API, but when I return that value, I get an "Undefined" instead.
I feel like the problem is in the way that I return that variable, but like I said I haven't been able to find an answer, so if someone know how to that would be wonderful.
Here is the function:
const CheckSource = async function(AttId, symbolId){
//creates the get parameters
var SourceGetParams = Helper.returnGetOptions(`SignalValues/${symbolId}/${AttId}`);
//send the get request and waits for responce
await Helper.sendRequest(SourceGetParams).then((res, body) => {
//parses the response, prints the correct value, but returns "undefined"
var response_body = JSON.parse(res.body);
var value = response_body.API_Signals[0].RawValue
console.log(value);
return Promise.resolve(value);
//error handling
}, (error) => {
console.log('error sending source get request:', error);
return Promise.reject('There was an error with the fusion request.');
}).catch((error) => {
console.log('Source sendRequest promise error:', error);
return Promise.reject('There was an internal error sending the request.');
}); }
I have tried to use different methods to return the value (such as 'return value;') but I get the same result.
Here is how I call the function:
CheckSource(<Att_ID string here>, <Symbol_ID string here>).then((data)=>{
console.log(data)
});
I know this is a question that is often asked, and I tried many of the other answers found here, but got no results.
The answer I get is this:
False //(this is the expected output from the conslole.log() in the async function)
undefined //(this is the console.log() after I called the function)
I really appreciate all of you.
What I can see in your code is, the function check source is returning a resolved promise from inside of another function and when you are calling it, you are trying to resolve the promise using then and catch. That should not be the case. Try a console log like this
console.log(CheckSource());
This should print False.

How to recover from errors in rxjs?

I'm trying to understand how to consume observable sequences and how to recover from errors.
My example is a bit contrived but my real implementation is a bit too complex to show here. Anyway, I have someObservable that emits values when the user clicks in the UI. This should trigger a request to the API (GET/POST/etc). The problem is that if the API returns an error, postData isn't called anymore after that.
I've make an example here that shows the problem. I've found that I can use Rx.Observable.of instead of Rx.Observable.throw to keep things running. But that will emit a value to the subscribe function. And in my real application postData is a service that is reused by multiple parts of the application and I'm not sure that I want to use of instead of throw there.
So my question is, how do you normally handle things like these?
let someObservable = Rx.Observable.timer(1, 1000);
someObservable
.switchMap(data => {
return postData(data);
})
.catch(error => {
console.log("POST failed");
})
.subscribe(val => console.log("Success: " + val));
function postData(data) {
console.log("Will post " + data);
if (data !== 2) {
return Rx.Observable.of(true);
}
else {
return Rx.Observable.throw(new Error("400 Bad Request or something"));
}
}
http://jsbin.com/naroyeyive/3/edit?js,console
If you want to send the request again, you may want to look into retry and retryWhen instead of catch.
catch will use the returned Observable as new "source". See this bin for an example.
retry(When) will "re-subscribe" whenever an error occurs, based on the configuration you pass to the operators. You can find examples and more information here: https://www.learnrxjs.io/operators/error_handling/retrywhen.html

Firebase's .once() Query Method Doesn't Stop Listening After Being Called [duplicate]

This question already has answers here:
node process doesn't exit after firebase once
(4 answers)
Closed 7 years ago.
I'm a totally new Firebase user, trying to build a simple application -- and I'm running into an odd issue that I haven't been able to find a solution to.
Here's what I'm doing.
I've got a simple Firebase database of users, that looks something like this:
{
"users": {
"randomlyAssignedId": {
"phoneNumber": "+18882223333"
}
}
}
The idea is that I'll have one user object (and each user object only contains a phoneNumber field) for each user using my service.
I've got this stored in Firebase and working already.
Now, here's where things are getting tricky. I want to write a query which returns a user by their phoneNumber. So, after reading the Firebase docs, here's what I came up with:
var Firebase = require('firebase');
var users = new Firebase('https://demo.firebaseio.com/users');
users.orderByChild('phoneNumber').equalTo('+18882223333').limitToFirst(1).once('value', function(snapshot) {
console.log('API call succeeded:', snapshot.val());
}, function(err) {
console.log('Firebase returned an error:' err);
});
When I run this code sample, the user object is logged to the console successfully (it found the match, yey!), however -- the callback never finishes.
According to the Firebase docs for .once(): https://www.firebase.com/docs/web/api/query/once.html the success (or error callback) should fire exactly ONE time.
This doesn't appear to be happening :(
Could anyone tell me if this is the desired behavior, or if I'm doing something wrong?
Thanks! <3
I think what you're expecting is just a little off.
You have 2 functions in your .once() call :
.once("value",function(snapshot){
....
},function(err){
console.log('Did not find a user in the database:');
console.log(err);
})
However, the 2nd function where you are looking for a possible err value is not going to be utilized if the data is not found. The 2nd function is there to catch a lack of authorization/permission. I think you are looking for something like this:
.once("value",function(snapshot){
if(snapshot.val()){
console.log('Found existing user by phoneNumber in database:');
console.log(snapshot.val());
}else{
console.log('Did not find a user in the database:');
console.log(err);
}
},function(err){
console.log('Not authorized');
console.log(err)
})
If your data (user's phone number) is not found in the database then the result of the snapshot.val() will be null. The 2nd callback function will only contain an err value if you have auth rules set on your firebase and they are not met when making this request.
You can read more here:
https://www.firebase.com/docs/web/api/query/once.html

Javascript event sequence, pg, postgresql, why?

I am trying to write a javascript file in express to talk to a postgresql database. More precisely, I want to write a function that takes SQL as an input parameter and returns the stringified json. I can assume memory is not an issue given these table sizes. This is paid work making an internal use tool for a private business.
My most recent attempt involved the query callback putting the value into a global variable, but even that still fails because the outermost function returns before the json string is defined. Here is the relevant code:
var dbjson;
function callDB(q) {
pg.connect(connectionString, function(err, client, done) {
if (err) {
console.error('error fetching client from pool', err);
} else {
client.query(q, [], function(err, result) {
client.query('COMMIT');
done();
if (err) {
console.error('error calling query ' + q, err);
} else {
dbjson = JSON.stringify(result.rows);
console.log('1 ' + dbjson);
}
console.log('2 ' + dbjson);
});
console.log('3 ' + dbjson);
}
console.log('4 ' + dbjson);
});
console.log('5 ' + dbjson);
}
The SQL in my test is "select id from users".
The relevant console output is:
5 undefined
GET /db/readTable?table=users 500 405.691 ms - 1671
3 undefined
4 undefined
1 [{"id":1},{"id":2},{"id":3},{"id":4}]
2 [{"id":1},{"id":2},{"id":3},{"id":4}]
Why do the console logs occur in the order that they do?
They are consistent in the order.
I attempted to write a polling loop to wait for the global variable to be set using setTimeout in the caller and then clearing the timeout within the callback but that failed, I think, because javascript is single threaded and my loop did not allow other activity to proceed. Perhaps I was doing that wrong.
While I know I could have each function handle its own database connection and error logging, I really hate repeating the same code.
What is a better way to do this?
I am relatively new to express and javascript but considerably more experienced with other languages.
Presence of the following line will break everything for you:
client.query('COMMIT');
You are trying to execute an asynchronous command in a synchronous manner, and you are calling done(), releasing the connection, before that query gets a chance to execute. The result of such invalid disconnection would be unpredictable, especially since you are not handling any error in that case.
And why are you calling a COMMIT there in the first place? That in itself looks completely invalid. COMMIT is used for closing the current transaction, that which you do not even open there, so it doesn't exist.
There is a bit of misunderstanding there in terms of asynchronous code usage and the database also. If you want to have a good start at both, I would suggest to have a look at pg-promise.

Nodejs asynchronous database function needs synchronous answer

I am new to nodejs and am writing some code that needs to query my MySQL database and return a username from a given user_id. I've been reading that all your functions should be asynchronous. In this case, ideally I would like the server to be able to respond to other event requests while this query is taking place. However, it isn't a particularly large query and only returns a single value. Maybe I should make it synchronous? (If that is your answer, sample code to change it would be great) Anyways, here is my function. It gives an error near the last line "return current_username;" because current_username is undefined at that point. Any suggestions?
function get_current_username(current_user_id) {
console.log(' | Entered get_current_username');
sqlq = 'SELECT username FROM users WHERE id = ' + current_user_id;
connection.query(sqlq, function(err, rows, fields) {
if (err) throw err;
var current_username = rows[0].username;
console.log(' | the current_username =' + current_username);
});
return current_username;
}
Pass in a callback function to get_current_username and then call that callback function from inside of connect.query's callback:
function get_current_username(current_user_id, callback) {
console.log(' | Entered get_current_username');
sqlq = 'SELECT username FROM users WHERE id = ' + current_user_id;
connection.query(sqlq, function(err, rows, fields) {
if (err) throw err;
var current_username = rows[0].username;
console.log(' | the current_username =' + current_username);
callback(current_username);
});
}
When you go to use this function then, you'd do something like:
get_current_username(12345, function(username) {
console.log("I am " + username);
});
You could also check out the use of promises/futures. I have a feeling I won't be able to do an explanation of these justice, so I'll link off to this StackOverflow question about understanding Promises.
This is an architectural decision though - some people would prefer to use callbacks, especially if writing a module intended for re-use by 3rd parties. (And in fact, it's probably best to get your head fully wrapped around callbacks in the learning stages here, before adopting something like Promise.)

Categories

Resources