react-toastify icon indicating copy to clipboard operation
react-toastify copied to clipboard

toast.update fail sometimes

Open lokomass opened this issue 2 years ago • 4 comments

Hi.

Before sending a request to my back, I create a toast with a loading gif inside, and a blue background like this :

image

When, I receive a response from my back, I update my toast : set it to success or error, and change text/background. It's work 9 times out of 10...

Sometimes, toast.update update only text inside but not className and type.

Here is an example call to back :

export const myTest = () => {
  const toast = get_id(6) //random id generated
  print_loading(toast)
  return (dispatch) => {
    const data = JSON.stringify({
      //...
    })
    api(data)
      .then(data => {
        if (data.status === 'OK') {
          update_toast(toast, data.response, 'success')
        } else {
          update_toast(toast, data.response, 'error')
        }
      })
      .catch(() => {
        update_toast(toast, undefined, 'error')
      })
  }
}

This in my toast functions :

// print loading toast
export function print_loading(id, texte = () => <CircularProgress style={white}/>, delay = 5000) {
  toast.info(texte, {
    toastId: id,
    icon: false,
    draggable: true,
    autoClose: delay,
    theme: 'colored',
    closeButton: false,
    pauseOnHover: true,
    closeOnClick: true,
    progress: undefined,
    hideProgressBar: true,
    position: 'bottom-right',
    bodyClassName: 'circular-toast',
    className: (typeof texte !== 'string')
      ? 'loading-toast'
      : undefined
  })
}
//update the toast
export function update_toast(id, texte = 'Une erreur est survenue', type = 'success') {
  toast.update(id, {
    type: type,
    delay: 500,
    icon: false,
    render: texte,
    draggable: true,
    theme: 'colored',
    closeButton: false,
    pauseOnHover: true,
    closeOnClick: true,
    progress: undefined,
    className: undefined,
    hideProgressBar: true,
    position: 'bottom-right',
    autoClose: 5000
  })
}

And the result of 10 test :

image

On of them is text updating but not parent class and type.

Here is my css :

.loading-toast .circular-toast {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0!important;
  margin: 0!important;
}
.loading-toast .circular-toast > div {
  display: flex;
  flex: 0 0!important;
}
.loading-toast {
  width: 64px;
  height: 64px;
}

Thansk for helping

lokomass avatar Mar 16 '23 11:03 lokomass

Here is a sandbox, but this doesn't reproduce my problem, it's inexplicable : https://codesandbox.io/s/magical-water-t3o9nr?file=/src/App.js

lokomass avatar Mar 16 '23 16:03 lokomass

I'm using 9.0.1 version, and same issue with last version

lokomass avatar Mar 20 '23 09:03 lokomass

@lokomass if you are not able to reproduce the issue but still have it in your project, I suspect that something is happening on your side. Really hard to tell what is going on this way.

Have you thought about using the toast.promise API?

https://fkhadra.github.io/react-toastify/promise/

fkhadra avatar Mar 21 '23 19:03 fkhadra

ive been getting this issue too.

i have been using this with tanstack react-query to notify users of theire actions i use an toast.info on the API initial request to tell the user that they have sent the request and once the API sends back a success or error it will update the same toast with the results and appropriate type.

i use this for long requests so the user knows that the site is processing their request.

but it is only happening sometimes, almost all the time it will work and update the toast with the success and all is good, but every now and then the update wont work and from that point on all updates dont work until i refresh the page.

const mutation = useMutation(update, {
    onMutate: (data: TUpdate<any>) => {
      const message = data.message ? data.message : "Updating Record";
      setOriginalMessage(message);

      const id = toast.info(createMessage(message), { autoClose: false });
      setToastId(id);

      if (onMutate) {
        onMutate(data);
      }
    },
    onError: (data: any) => {
      if (data.errors) {
        const entries: [string, string[]][] = Object.entries(data.errors);
        entries.forEach(([key, errors]) => {
          handleErrors(errors, key);
        });
      } else if (data.error) {
        handleError(data.error);
      } else if (data.result) {
        queryClient.invalidateQueries(refetchKeys);
        ensureToastIsActive("warning", "Submission Halted - Validation Issues");
      }
      if (onError) {
        onError(data);
      }
    },
    onSuccess: (data: any) => {
      if (data.errors) {
        const entries: [string, string[]][] = Object.entries(data.errors);
        entries.forEach(([key, errors]) => {
          handleErrors(errors, key);
        });
      } else if (data.error) {
        console.log("data -------------- error ", data);

        handleError(data.error);
      } else if (data.result) {
        console.log("data -------------- success ", data);

        queryClient.invalidateQueries(refetchKeys);
        ensureToastIsActive("success", `${originalMessage} - Succeeded` ?? "");
      } else {
        console.log("data -------------- ", data);
      }
      if (onSuccess) {
        onSuccess(data);
      }
    },
  });
  
  const ensureToastIsActive = (type: "error" | "success" | "warning", render: string) => {
    console.log("toastId -- ", toastId);
    if (toastId !== null) {
      console.log("toast.isActive(toastId) -- ", toast.isActive(toastId));
    }
    if (toastId !== null && !toast.isActive(toastId)) {
      setToastId(toast[type](render));
    } else if (toastId !== null) {
      console.log(`got here --- type: ${type} - render: ${render}`);

      toast.update(toastId, {
        type: type,
        render: render,
        autoClose: 5000,
      });
    }
  };

when it wasn't working i used those traces to see if there was anything entering the toast to cause it an issue, but it all looks good.

jkoufalas avatar Oct 26 '23 03:10 jkoufalas