I'm wondering if await and .then can be used in the same async function? Here is my function:
uploadImageToImgur: async function (file) {
return new Promise(function(resolve, reject) {
const url = 'https://api.imgur.com/3/image',
reader = new FileReader();
if (file) {
reader.readAsDataURL(file);
}
reader.onloadend = async function () {
let { result } = reader;
try {
const request = await fetch(url, {
method: 'POST',
headers: {
"Authorization": 'my auth',
},
body: result.replace(/^data:image\/(png|jpg|jpeg|gif);base64,/, "")
})
.then((response) => {
response.json()
.then(data => {
resolve(data.data.link)
})
});
} catch (e) {
reject(e);
}
}
});
},
Then I call this function in another one where I save the object to indexedDb with the link i've got from the imgur API.
this.uploadImageToImgur(image)
.then((image) => {
let db = this.dbOpen.result,
tx = db.transaction('EventsStore', 'readwrite'),
store = tx.objectStore('EventsStore');
event = store.put({ title, location, description, summary, date, time, image });
//rest of the code
});
Why did I choose this approach? Because when I used only await keyword (without promise constructor), data was adding to the db before promise was resolved ;/ What was not what I wanted (probably I made a mistake somewhere.. idk).
My question is if the code above is the correct way to do that (it works as intended) or should I refactor it? If so, please tell me how. This question is rather informative for me than related with a specific problem. Thank You.
Yes, you can use mix await
and then
syntax - they both work on promises - but you shouldn't do so in the same function.
But that's not the main issue in your code. The problem is the use of the Promise
constructor antipattern in the uploadImageToImgur
function. Do not use async function
s as callbacks. Do not create promises in then
callbacks without return
ing them - rejections of response.json()
are not caught by your code.
Yes, you will need the Promise
constructor to promisify the reader, but that's it. Factor it out inside its own function so that you don't lead yourself into temptation. That if (file)
condition inside the executor led to your promise being never resolved in some cases!
Cleaned up:
function readDataUrl(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function() {
resolve(this.result);
};
reader.onerror = reader.onabort = reject; // don't forget this!
reader.readAsDataURL(file);
});
}
uploadImageToImgur: async function(file) {
const url = 'https://api.imgur.com/3/image',
if (file) {
const result = await readDataUrl(file);
const response = await fetch(url, {
method: 'POST',
headers: {
"Authorization": 'my auth',
},
body: result.replace(/^data:image\/(png|jpg|jpeg|gif);base64,/, "")
});
const data = await response.json();
return data.data.link;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With