This question already has answers here:
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 3 years ago.
I have 2 variables. One is assigned inside a .then and the other assigned in a function. Later on only 1 is defined.
Code excerpt...
let user;
let station;
const app = express();
app.post("/api/user", (req, res) => {
user = req.body.user; // Breakpoint added here to confirm user set
}
// Uses serialport module. Called when data received on serial port
function serialPortListener(data) {
getStation(data) // Retrieves record from database
.then(s => {
station = s; // Breakpoint added here to confirm station set
...
}
I set breakpoints on both methods to confirm the variables are set. When I try to access them, later on, only user is defined. I'm assuming it's something to do with the context in which station is set?
station is not assigned anywhere else.
I believe the problem is due to the way var and let works. Try changing let with var, it should work. For the differences between var and let read this.
Edit: Ran the code here is a working code.
let user;
let station = 'ABC';
let getStation = new Promise(function (resolve, reject) {
setTimeout(() => resolve('XYZ'), 1000);
});
// Uses serialport module. Called when data received on serial port
function serialPortListener(data) {
getStation
.then((s) => {
console.log(station); // station is available with value ABC
station = s;
console.log(station); // station has value changed to XYZ
});
}
console.log(serialPortListener('data'));
The problem in your codes is in the line
getStation(data)
Related
This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 1 year ago.
I am trying to get a shared key based on whether it already exists in the db or not. I am using Firebase store database.
The problem is that even though i assign passkey some value inside the sub-function, when I do console.log outside the function, it just prints the original passkey which was set at declaration.
I have tried using window.passkey and window.global.passkey by declaring passkey as global variable, outside all functions, but it didn't work.
I am working with a node.js project. My code is as follows:
// var passkey = {"shared_key":""} // Declaring passkey as global variable but didn't work.
const onSubmit = (formData) => {
const email_id = getUserDetails().email;
const from_db = db.collection(email_id);
const to_db = db.collection(formData.to);
var passkey = {"shared_key": ""};
// Check if there exists a shared key between `from` and `to`
// Checking for shared key in either of the db is enough.
to_db.doc(email_id).get().then((res) => {
// assume that res.exists is true.
if (res.exists) {
passkey.shared_key = res.data().shared_key; // passkey is set here
} else {
// Generate and use a shared key
...some code to generate a shared key ...
passkey.shared_key = generated_key;
}
});
console.log(passkey);
// above prints {"shared_key": ""} instead of printing the value of shared key taken from the database.
// or the one that is generated!
};
I know it is related to variable hoisting in javascript but I think there has to be some workaround.
Any help/comment is appreciated. Thanks in advance.
When you code with this pattern
function doIt () {
var something = ''
invokeFunction()
.then (function handleResult (result) {
console.log('2', something)
something = result
} )
console.log('1', something)
}
your console.log('1', something) runs before the inner function (I named it handleResult for clarity) is ever called. That's because invokeFunction() is asynchronous; it returns a Promise object.
You could rewrite this as follows:
async function doIt () {
var something = await invokeFunction()
console.log('1', something)
}
to get the kind of result you want.
With respect, you will have a very hard time coding Javascript unless you take the time to learn about async / await and Promises. In that respect the Javascript language is very different from other languages. Drop everything and learn that stuff now. Seriously.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
I am trying to learn the concept of promise and implement in angular. Here is my code in stackblit. What I am trying to achieve is , I have want to show the array whenever it is assigned with any value using promise in angular.
My Html Code is :
<h2>Array values</h2>
<p *ngIf="show">
<span *ngFor="let values of filter">
{{values}}
</span>
</p>
My TS file is :
filter = [];
show = false;
ngOnInit() {
this.showArray();
}
showArray() {
var a = new Promise(resolve=>{
setTimeout(() => {
this.filter = [3, 4, 4]
resolve('resolved');
}, 0);
});
a.then(function() {
this.show= true;
})
}
Whenever my array is assigned with any values(which might be from a remote API), I want to set the variable show to true. I am not getting the result. I have gone through many examples related to promise but couldn't found a working example of promise in this fashion.
Replace your code with -
a.then(() => {
this.show= true;
})
you need to use arrow function instead of existing one.
If you are using this piece of code -
a.then(function() {
this.show= true;
})
this will not bind to show variable which is of class level but template binding is done with class level variable, that is why existing code is not working.
Working Example
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How can I save information locally in my chrome extension?
(2 answers)
Closed 5 years ago.
I have a string which I need in multiple functions. Therefore I want to save it in a variable. But when I try to assign it inside a function it doesn't update the variable.
var auth_code = "na";
function safeAuthCode(authcode){
auth_code = authcode;
console.log(auth_code);
}
"auth_code" prints just fine in the console at that point, but when I try to use it later it just contains "na". Not sure what I'm doing wrong tbh :/
Edit:
This is the function in which safeAuthCode is called:
function auth(){
chrome.identity.launchWebAuthFlow({
"url": "https://accounts.spotify.com/authorize?client_id="+client_id+
"&redirect_uri="+ encodeURIComponent(redirectUri) +
"&response_type=code"+
"&scope=" + encodeURIComponent(scopes),
"interactive": true
},
function(redirect_url) {
var url = new URL(redirect_url);
var code = url.searchParams.get("code");
safeAuthCode(code);
});
}
I am assuming that the problem you are having is because of the global variable that either gets overwritten in a different part of the code, or because your code at a certain point in time reloads, and the initial value gets reset.
To save such authentication code, you could make use of the sessionStorage object of your browser.
To make sure you only have 1 such object, you could use the const keyword to define your variables (in case another definition of that variable would come at a later time, you should get an error thrown)
const authorisationSettings = {
get code() {
return sessionStorage.getItem('authorisationCode') || 'na';
},
set code(value) {
return sessionStorage.setItem('authorisationCode');
}
};
function saveAuthorisationCode( code ) {
authorisationSettings.code = code;
}
saveAuthorisationCode( 'test' );
console.log( authorisationSettings.code );
This snippet doesn't work on stackoverflow, so you can find the jsfiddle here
It happens because of when your function is executed, in lexical environment of that function is already exist authcode variable and you are trying to set this one instead of global authcode
You need to change name of global variable or param of the fuction...
This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
This code is an external file, test.js, which is linked to from index.html, after the jQuery file.
When I refresh my browser and go into the console, I get this error message:
Uncaught TypeError: Cannot read property 'starshipName' of undefined
on line 20, where I try to alert the starshipName property of the first item in the array.
var starships = [];
function starship(starshipName, model, manufacturer) {
this.starshipName = starshipName;
this.model = model;
this.manufacturer = manufacturer;
}
function starshipData(data) {
for (i = 0; i < data.results.length; i++) {
var results = data.results[i];
starships.push(new starship(results["name"], results["model"], results["manufacturer"]));
}
}
$.getJSON('https://swapi.co/api/starships/', function(data) {
starshipData(data);
});
alert(starships[0].starshipName);
However, when I type out the last line of code or log the starships array to the console, it works perfectly. I am very confused as to why this is happening and will appreciate any help! Thank you in advance.
$.getJSON is an asynchronous function. This means that your alert() is called before starships is filled with data - hence the undefined property error.
All operations that depend on an async function must be placed in, or called from, the callback. Try this:
$.getJSON('https://swapi.co/api/starships/', function(data) {
starshipData(data);
// 1: place the call in the callback
// 2: always use console.log to debug as it does not coerce data types
console.log(starships[0].starshipName);
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
Background:
I'm building a simple program that uses the simpleWeather.js API to pull in the current temperature to be used by the rest of the program (http://simpleweatherjs.com/).
Updated Code:
All the below code is within an AngularJS controller and the simpleWeather.js file is linked in the index.html file.
var _this = this;
var seasons = null;
function myAjaxCheck(callBack){
$.simpleWeather({
location: 'Calgary, CA',
woeid: '',
unit: 'c',
success: function(weather) {
var temperatureTemp = parseInt(weather.temp);
callBack(temperatureTemp);
}
});
}
var temperature;
myAjaxCheck(function(returnedTemperature){
temperature = returnedTemperature;
if (temperature > 20){
_this.seasons = summerCollection; <-- summerCollection is an array strings
}
});
Alternative that works:
var _this = this;
var seasons = null;
var test = function(){
_this.seasons = summerCollection;
};
test();
UPDATE: Problem:
It seems that I can update the global variable with the member function test() as in the 2nd snippet of code. However, why isn't the global variable updated with the AJAX callback function in the 1st snippet of code?
I have a div in my HTML that uses ng-repeat to spit out all the strings in the summerCollection array.
It works with the 2nd snippet of code but does not with the first.
Any help is greatly appreciated!
Any ideas?
Original Problem:
From what I gathered from the web inspector, it appears that the order in which this code loads is (which it should not):
a. $.simpleWeather({...
b. alert(temperature)
c. success: function(weather){...
Any ideas why this is? I know that if I put alert(temperature) in the success:function(weather){} then it'll return the current temperature but this is not what I want.
I ultimately want the variable temperature to hold the current temperature so that I can use this variable in other functions. For instance, I want to be able to set "seasons" to different strings according to the temperature value.
Any help is greatly appreciated!
Well this is the nature of callbacks - they are asynchronous. The code is supposed to run in the order you described.
And what you're doing is correct, except that the alert is running BEFORE your callback is complete (as it should).
So what you need to do is put your alert (and the real code that you want to run), into the callback:
var temperature = null; <-- this variable should store the temperature retrieved by simpleWeather API
var seasons = null;
$.simpleWeather({
location: 'Calgary, CA',
woeid: '',
unit: 'c',
success: function(weather) {
temperature = parseInt(weather.temp); <-- Temperature variable defined outside this scope
alert(temperature);
// call your remaining code here, which will run after the temperature has been set.
some_other_function();
}
});
function some_other_function() {
}