I have an async function that I would like to return a value from and then use.
Within the updatedStyleSheet function, I'd like to return the updated_css so that I can use it somewhere else.
async function updatedStyleSheet() {
const res = await fetch("./prism.css");
const orig_css = await res.text();
let updated_css = orig_css;
const regexp = /(?:var\(--)[a-zA-z\-]*(?:\))/g;
let cssVars = orig_css.matchAll(regexp);
cssVars = Array.from(cssVars).flat();
for (const v of cssVars) {
updated_css = updated_css.replace(v, colors[v.slice(6, -1)]);
};
// return updated_css ?
}
If I call this function, I get a Promise object. Rightfully so, since async functions always return a promise.
Could I return the updated_css within the updatedStyleSheet function and do something like this after?
const newSheet = updatedStyleSheet().then(css => css)
Then use the newSheet variable wherever in my script?
End Goal
Take the updated_css that contains the text contents of my CSS and use it as an href value so the user can download the stylesheet.
Edit
I attempted to add an event handler so that all the selected color values would be saved in the stylesheet once the user saves it, but it doesn't seem to work. I know it is still an issue with my understanding of promises as a whole.
What I did.
const updatedStyleSheet = async () => {
const res = await fetch("./themes/prism.css");
const orig_css = await res.text();
let updated_css = orig_css;
const regexp = /(?:var\(--)[a-zA-z\-]*(?:\))/g;
let cssVars = orig_css.matchAll(regexp);
cssVars = Array.from(cssVars).flat();
console.log(cssVars)
for await (const variable of cssVars) {
const trimmedVar = variable.slice(6, -1)
const styles = getComputedStyle(document.documentElement)
const value = String(styles.getPropertyValue(`--${trimmedVar}`)).trim()
updated_css = updated_css.replace(variable, value);
}
console.log(updated_css)
return updated_css
}
const main = async () => {
const downloadBtn = document.getElementById('download-btn')
downloadBtn.addEventListener('click', () => {
const updated_css = updatedStyleSheet()
downloadBtn.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + encodeURIComponent(updated_css))
downloadBtn.setAttribute('download', 'prism-theme.css')
})
}
main()
I can't await the updated_css because it falls into the callback of the click event, which is a new function.
Then I did the following thinking it would work since it was top level.
const downloadBtn = document.getElementById('download-btn')
downloadBtn.addEventListener('click', async () => {
const updated_css = await updatedStyleSheet()
downloadBtn.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + encodeURIComponent(updated_css))
downloadBtn.setAttribute('download', 'prism-theme.css')
})
That gave me the following error TypeError: NetworkError when attempting to fetch resource.
cssin thethencallback would be your returned item but it doesnt return it to the outside you will just get another promise. You cant go from async code and then back to the outside sync codenewSheetis again going to be aPromise. As @PatrickEvans said, "You can't go from async code and then back to the outside sync code". However, as you said you want to use it as an href value, you can do that inside.then().