This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed last year.
Whenever I try to get data from chrome.storage, it returns undefined.
chrome.storage.sync.get('courses', function(result) {
currentCourses = result.courses
console.log(currentCourses)
currentCourses.push(coursename)
chrome.storage.sync.set({courses: currentCourses}, function() {
alert(`Course "${coursename}" has been added !`)
});
}
userCourses = async () => {
await chrome.storage.sync.get('courses', function(result) {
return(result.courses)
});
}
courseData = userCourses()
console.log(courseData)
I found an answer here on stack overflow, but it is giving the same error. I am new to JS, and not comfortable with Promises.
I tried the example from the official docs, but it is also giving the same error as below.
Can someone help me with a solution, or modify my code ?
Wrap the call to storage in a promise and await it:
function getStorageValuePromise(key) {
return new Promise((resolve) => {
chrome.storage.sync.get(key, resolve);
});
}
await getStorageValuePromise('val');
You use chrome.storage.sync.get() with a completion callback. But notice that the data you retrieve using that .get() method isn't available except within the callback.
chrome.storage.sync.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
});
is the example from the docs. It is the invocation of a function. But that function always and necessarily returns undefined.
Notice that the first parameter to .get() is an array of keys. Your code lacks the array.
The second parameter is the callback function. It looks like this:
function (result) {
}
Within the function result.key is the key you requested, and result.value is whatever you stored in the key. You're looking at result.courses, which isn't defined.
Control flow.
The call to .get() completes immediately, always.
At some later time the callback is called.
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed last year.
First Post, so forgive me for any general practices that I haven't followed.
Also very new to Chrome extension and Javascript so apologies for my noob question
I have the following code but getting the console is say undefined
function getFromStorage(key) {
chrome.storage.sync.get(key, function (r) {
const returnVal = r[key]
console.log(returnVal)
return returnVal
})
}
chrome.contextMenus.onClicked.addListener((selectionText) => {
var Val = getFromStorage("value")
console.log(Val)
});
But when I run the chrome.storage.sync.get in the listener, it works fine.
I have a few values from storage that I want to grab so thought a function would be better.
btw, using Manifest V3
Thank you in advance
The problem is that your getFromStorage doesn't return anything. It just calls an asynchronous API, then the callback runs and returns a value into the internals of the chrome API, which simply ignores this value.
Since chrome.storage returns a Promise in modern Chrome you can just await it directly.
Note that the function should be declared as async to allow using await inside.
async function getFromStorage(key) {
return (await chrome.storage.sync.get(key))[key];
}
chrome.contextMenus.onClicked.addListener(async info => {
let Val = await getFromStorage('value');
console.log(Val);
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
This question may have been asked here before, and I'm sorry, but I wasn't able to find a solution to my problem anywhere. I am relatively new to JavaScript and things like "promises" are alien to me. I am trying to make a code that will load an array from a .JSON file, and after it loads, the code will continue.
async function fetchTags() {
var response = await fetch('../json/tags.json');
var json = await response.json();
console.log(json); // returns: Array()
return json;
}
function mainFunction() {
let tags = fetchTags();
console.log(tags); // returns: Promise { <state>: "pending" }
}
This is what my current code looks like, using a not-working "solution" I found on the internet. While the console.log(json), which is inside of the async function, returns the array correctly, the main function's console.log(tags) displays this promise with a "pending" state - and displays sooner than the array can be loaded, if I understand correctly.
The following code of the mainFunction() however relies strongly on this array, and it should not proceed before the array is loaded. Where am I making a mistake?
Thanks a lot for all your replies.
At this point, fetchTags is an asynchronous function and needs to be treated as such when calling it. You have two implementation options here:
Use async/await for your mainFunction function:
async function mainFunction() {
let tags = await fetchTags()
console.log(tags)
}
Appropriately handle the promise that is returned by the function:
function mainFunction() {
fetchTags()
.then(console.log)
.catch(console.error)
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I'm trying to make a function that returns a string containing a jwt token, the function used in Amplify returns a promise and I can't get my head around promises but after some struggling, I've managed to get my function to get the string I need from the promise and print it to the console but when I then return this string from the function so I can call it from various places the resulting data is now a promise again. No idea what I'm doing wrong.
async function getToken() {
let userData = await Auth.currentAuthenticatedUser().then(result => result.signInUserSession).then(result => result.accessToken).then(result => result.jwtToken);
console.log(userData); // this prints the token perfectly as text to the console
return(userData); // I want this to return the token as a string not a promise
}
console.log(getToken(); // this prints a promise to the console again even though I've got it to a string in the function.
If you have used await inside a function than it will only return a Promise no matter what so you can just use
getToken().then(console.log)
// or
getToken().then(token => console.log(token))
// both are same
since you can not use await outside an async function as a matter of react application just use state such as update the state of application using setState() in the .then of the promise returned. there is no such need of making the function async.
or if you really want the component to be async than just study <Suspense> in react to handle the components that have to fetch data from a network before being displayed
use it like this.
let result = null
getToken().then(token => {
result = token
// Now you can use the result variable
console.log(result)
})
Think I've sussed it now thanks to #tfarmer4 and #Arish Khan. In my head I wanted to get the token as a string variable so I could pass it into my API call functions but I realise now I will need to call it from within each function so below is my example solution.
function getToken() {
return Auth.currentAuthenticatedUser().then(result => result.signInUserSession).then(result => result.accessToken).then(result => result.jwtToken);
}
function callAPI () {
getToken().then(data => {
let token = data;
console.log(token);
//more lines here such as calling my API using token as the variable of the jwt token
}
);
};
EDIT: Sandbox here All you need is this edit I believe. Remember that async functions are just promises. You have to do any work on the result by either setting the result to a variable with an let data = await Auth.currentAuthenticatedUser().then(result => result).then(data => data.jwtToken), or just do all the necessary work in the .then(data => {data.jwtToken //...your work here}).
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
Using NodeJS, I'm trying to get info from the database on a list of IDs and populate an array of objects. I need this to process synchronously. I'm having trouble figuring out how to do this so the next function call will wait for the previous one to finish before being called. Then all of the 'each' iterations to finish for the return to be called.
Example:
getInfo();
function getInfo(){
var return_arr = Array();
var ids = getListOfIDs();
// loop through each id getting more info from db
$.each( ids, function( i, v ){
return_arr.push(getFullInfo( id ));
});
return return_arr;
}
function getListOfIDs(){
// database call to get IDs
// returns array
}
function getFullInfo(){
// database call to get full info
// returns object
}
This is a simplified example, so assume that a single query to get all info will not work as there are multiple joins going on and post processing that needs to take place in js. Also, assume I'm doing proper error handling, which I omitted in my example.
Your database queries are asynchronous so you need to either use callbacks or promises to perform your work once the database returns with results.
function getListOfIDs(callback) {
// database call to get IDs
db.query('...', function(data) {
// call the callback and pass it the array
callback(data);
});
}
function getInfo() {
// pass an anonymous function as a callback
getListofIDs(function(data) {
// we now have access to the data passed into the callback
console.log(data);
});
}
Your current code example is synchronous, although I don't know how your db code works. The each loop is synchronous it just iterates over your ids and calls the getFullInfo function.
I'm not sure why you want synchronous code though as it doesn't utilise Nodes event loop architecture.
What I would do is use a good Promises framework such as Bluebird (http://bluebirdjs.com/docs/api/promise.each.html) with Promise.each ensuring each iteration occurs serially. Or you could also use a Callback library such as async (http://caolan.github.io/async/) with async.eachSeries. Either of these will ensure that you (a) get the benefit of asynchronous and (b) iterate in a serial fashion.
Promise way to do it:
function getListOfIDs() {
return new Promise((resolve, reject) => {
// database call
if (err)
{
reject(your_db_err);
return;
}
resolve(your_db_result);
});
}
function getInfo() {
getListOfIDs().then((result) => {
//do whatever you want with result
})
.catch((err) => {
//handle your err
});
}
This question already has answers here:
jQuery deferreds and promises - .then() vs .done()
(11 answers)
Closed 7 years ago.
There is not much answer for this simple question that I have. My main question is that I have seen the .then method used a lot in JavaScript and I know the main thing where randomobject.then(//This returns success, //this returns failure). But there are things that I don't get such as the code here:
var success = function (response) {
return response.data;
};
var error = function (errResponse) {
$log.error(errResponse.data.Message);
};
function getsomeData() {
var url = baseUrl + 'api/somedata';
return $http.get(url).then(success, error);
}
First off in that code I'm wondering how the var success knows what data it is getting and the same with error. It says response.data but what is response? It's probably the result of the http.get but that doesn't make much sense code wise. Also it seems that when I have a function for example.
getsomeData returns what it returns. Why doesn't it work if I do the ff:
var dataHolder = randomAngularService.getsomeData()
it returns an object that holds a data under $$state but somehow the .then makes it work if you do the ff:
randomAngularService.getsomeData().then(function (response) {
if(response != null) {
console.log('got the data');
$scope.meeData = response;
}
});
I thought the .then only takes two parameters? This is what's confusing me.
Also is the .then property a JavaScript method or a jQuery one?
It's used to replace (or provide an alternate way) the old callback mechanism with a cleaner way to handle asynchronous requests, instead of passing your callbacks as parameters, you can chain your function with .then, given function will be executed once the promise gets resolved.
Anyhow, this is just a basic explanation, you should really get into the books of promises for more info.
I'm lazy to explain the whole promise thing, but just to answer question about .then
The 2 arguments inside .then actually means "call this function when the promise is resolved(success)/rejected(failed)"
About the arguments inside the functions, they should be specified in the API, because the caller (for instance $http.get) get to decide what to pass when calling that function.