I am trying to achieve the following:
Using React + React Hooks + useEffect
So basically
{
id: "xxxxxxx",
status: "queued"
}
Is what I get back. Now the processing time varies, but I want to periodically check if the status has changed from "queued" to "completed". And while it's not completed, I want to display a loading spinner.
What would be the best way to do this? Would this be possible with promises / async functions? Or do I have to use some kind of interval to re-check the status periodically?
I am basically trying to use this in React: https://docs.assemblyai.com/walkthroughs#authentication
You could do something like this:
// Mocks - after the 2nd attempt getStatus will return "done"
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let attempt = 0;
const getId = async () => {
console.log("getId");
await delay();
return { id: "id1" };
};
const getStatus = async (id) => {
console.log("getStatus", { id, attempt });
attempt += 1;
await delay(1000);
return {
id,
status: attempt < 2 ? "queued" : "done"
};
};
export default function App() {
const [id, setId] = useState();
const [isDone, setIsDone] = useState(false);
useEffect(() => {
const effect = async () => {
const { id } = await getId();
setId(id);
};
effect();
}, []);
useEffect(() => {
let cancelled = false;
const effect = async () => {
let { status } = await getStatus(id);
while (status !== "done") {
if (cancelled) {
return;
}
await delay(1000);
status = (await getStatus(id)).status;
}
setIsDone(true);
};
if (id) {
effect();
}
return () => {
cancelled = true;
};
}, [id]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>{isDone ? "Done" : "Loading..."}</h2>
</div>
);
}
Note: this is simplified and does not cover error scenarios, but shows how this can be put together