emilkowalski / sonner

An opinionated toast component for React.
https://sonner.emilkowal.ski
MIT License
8.37k stars 263 forks source link

Allow awaiting `toast.promise` #462

Closed ajmnz closed 3 weeks ago

ajmnz commented 3 months ago

Issue:

Closes https://github.com/emilkowalski/sonner/issues/339

What has been done:

toast.promise now returns an unwrap method. This method returns a new promise that resolves or rejects when the provided promise does. Made sure to do this in a non-breaking way:

const result = await toast
  .promise(myPromise, { success: "Loaded", error: "Error" })
  .unwrap();

// `result` is now the resolved value of `myPromise`. In order to get the `id` we
// just have to use it like before

const id = toast.promise(myPromise, { success: "Loaded", error: "Error" }); // id = 3
const result = await id.unwrap(); // result = `myPromise` resolved value

Screenshots/Videos:

N/A

vercel[bot] commented 3 months ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sonner ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 27, 2024 0:56am
netspencer commented 2 months ago

would love to see this merged

panzerfausten commented 4 weeks ago

Hey I actually need this. Could @emilkowalski merge it please?

panzerfausten commented 4 weeks ago

Here's my workaround in case someone faces the same issue. You need to wrap it under a promise and call resolve() reject() accordingly :

const sendNewCodeWrapper = async () =>{

        return new Promise((resolve,reject) =>{
            toast.promise(API.users.sendNewAccessCode(email), {
                loading: t('sendingAccessCode'),
                success: (data) => {
                    setTimeout(() => {
                    }, 1000);
                    resolve(data);
                    return t('accessCodeSent');
                },
                error: (ex) => {
                    setIsSendingCode(false);
                    reject(ex);
                    return (ex?.response?.data?.localized_error || ex?.message || t('accessCodeSentError'));
                },
                finally: () => {
                }
            });
        });

    }