I'm trying to use Zod and validate video file input duration. The issue is that to load metadata, there needs to be async / await and this is where I've reach my Javascript mastery limit. This is what I'm trying to do, I think I'm on the right track but I cant figure out how to await it.
How do I make sure this code will await onloadedmetadata before returning a response ?
video: z
.custom<File>()
.refine(
(file) => file instanceof File && file.type.includes('video'),
'Must select a video file'
)
.refine(async (file): Promise<boolean> => {
const video = document.createElement('video');
video.preload = 'metadata';
video.onloadedmetadata = () => {
window.URL.revokeObjectURL(video.src);
console.log(video.duration);
if (video.duration < 303) return true;
};
video.src = URL.createObjectURL(file);
return new Promise((resolve) => {
});
}, 'video duration limit reached!'),
EDIT:
I worked out an alternative path. I changed zod check to number. And I do the metadata loading on the input field, and trigger zod validation when metadata is loaded
Zod:
video: z
.number()
.refine((duration) => duration < 303, 'Video duration limit reached!'),
Input:
onChange={(event) => {
const files = event.target.files;
if (!files) return;
const video = document.createElement('video');
video.preload = 'metadata';
video.onloadedmetadata = () => {
window.URL.revokeObjectURL(video.src);
console.log(video.duration);
onChange(video.duration);
form.trigger('video');
};
video.src = URL.createObjectURL(files[0]);
This is how I managed to do it as I originally intended
video: z.instanceof(File).refine(async (file) => {
return new Promise<boolean>((resolve) => {
try {
const video = document.createElement('video');
video.preload = 'metadata';
video.src = URL.createObjectURL(file);
video.onloadedmetadata = () => {
window.URL.revokeObjectURL(video.src);
const durationCheck = video.duration <= 303 ? true : false;
return resolve(durationCheck);
};
} catch (error) {
return resolve(false);
}
});
}, 'Video duration limit exceeded (5 min max)'),
New Javascript Skill unlocked -> 'Promisification'