I'm using jsmediatags to parse metadata from mp3 files. This function grabs the title from a file. Sadly it returns before the onSuccess callback is complete. This is a problem because after this function the data is serialized and sent off BEFORE song.title is ever set.
How can I wait until jsmediatags.read is actually complete to return. (it is not an async function).
const get_song = (song_path, album) => {
const song = {
title: null,
};
jsmediatags.read(song_path, {
onSuccess: function (tag) {
song.title = tag?.tags?.title;
console.info("set song fields", song.title);
},
onError: function (error) {}
});
console.info("return from get_song", song.title);
return song;
}
This outputs
"return from get_song null",
"set song fields TITLE"
And then I use song.title before it is actually set.
How can I redesign my code so that the serialization of song happens after this callback completes.
Sure, you can promisify it:
const get_song = async (song_path, album) => new Promise((resolve, reject) => {
jsmediatags.read(song_path, {
onSuccess: resolve,
onError: reject
});
});
And then use it, for instance in an async function with await:
(async () => {
const tag = await get_song(song_path, album);
song.title = tag?.tags?.title;
})();
const getSong = async songPath => {
var tag = await new Promise((resolve, reject) => {
new jsmediatags.Reader(songPath)
.read({
onSuccess: (tag) => {
console.log('Success!');
resolve(tag);
},
onError: (error) => {
console.log('Error');
reject(error);
}
});
});
return {
title: tag?.tags?.title;
}
}