Getting Chrome Storage Value from Function (Chrome Extension) [duplicate] - javascript

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);
});

Related

Unable to get array from chrome.storage [duplicate]

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.

Unable to reset array in asynchronous Node.js function despite using Callbacks [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Wait for all promises to resolve
(5 answers)
How to return many Promises and wait for them all before doing other stuff
(6 answers)
Using async/await with a forEach loop
(33 answers)
Closed last year.
So I am trying to create a basic web scrapper API, and I am using a common function PullArticle() with a nested loop to scrape articles with keywords (different sets of articles and different sets of keywords) depending on the GET request I send.
I need to reset the callback variable "article" between GET requests to keep the data separate, but it just adds on previous calls to each GET request which can duplicate data if I call the same request twice.
I have tried to use a callback function and previously a promise function on advice of StackOverFlow, as I was under the impression that the Topic.forEach function was running asynchronously causing the returned "article" to just return empty; however, I haven't been able to get it to work no matter what, and I was hoping somebody can point out what I'm, doing wrong here.
var article = []
function PullArticle (Topic, myCallback) {
article =[] // IF I LEAVE THIS RESET OUT ARRAY RETURNS EMPTY :(
Topic.forEach(TopicLoop => {
newspapers.forEach(newspapers =>{
axios.get(newspapers.address) // pulling html
.then((response)=>{
const html = response.data
const $ = cheerio.load(html) //allows to pickout elements
$(`a:contains(${TopicLoop})`,html).each(function () {
const title = $(this).text()
const url = $(this).attr('href')
article.push ({
title,
url: newspapers.base + url,
source: newspapers.name,
})
})
})
})
})
let sendback = article
myCallback(sendback)
}
In the same file I make a get request with
app.get('/TopicMatrix1',(req,res) =>{
PullArticle( Topic1, myDisplayer)
function myDisplayer (PrintArticle){
res.json(PrintArticle)
}
})
app.get('/SomeOtherTopic',(req,res) =>{
PullArticle()
etc
}
Also does anyone know why I can't make the function myDisplayer(), which prints out res.json a common function sitting outside the GET request, so separate GET requests can call it?

Javascript: How to wait for fetch result before continuing [duplicate]

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)
}

JavaScript returning a promise even though it prints a string to the console [duplicate]

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}).

problem in returning object from the .filter() function to another modules [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
//I tried to return messages from the .filter() to another modules. I am able to console.log() it but unable to return it. i tried returning object(manually created) from outside the .then() it worked. But when i tried to return it from inside .filter() it didnt work. is it a problem of asyn? please explain on the basis of this problem about how async/await to use here... p.s i have read some documentation about promises, async/await.. but am not clear enough to use it in practical way.
function loadChat() {
return model
.find()
.then((data) => {
data.filter((datas) => {
messages = datas.messages;
console.log(messages);
return messages;
});
})
.catch((err) => {
console.log(err);
return err;
});
// const ans = {
// name: "madhav",
// };
// return ans;
}
//calling modules code is here
messages = loadChat();
console.log("type of messages", typeof messages);
console.log(messages);
//emitting event to load previous chat
socket.emit("loadChats", loadChat());
//output
type of messages object
Promise { <pending> }
EDIT: I see the problem now. You need to properly pass data from the find function - It should look something like this:
model.find((data) => data.filter ... // The rest of your code)
Also, what kind of error message or console log are you getting?

Categories

Resources