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

toast.dismiss() - Dismiss all toasts of a toast container ID.

Open tonix-tuft opened this issue 6 years ago • 10 comments

Do you want to request a feature or report a bug? Feature.

We can use toast.dismiss() to dismiss all the toasts or toast.dismiss(toastId) to dismiss a specific toast.

When using multiple toast containers, Iis there a way to dismiss all the toasts of a toast container? E.g.: toast.dismiss({toastContainerId})?

Thank you.

tonix-tuft avatar Jan 10 '20 18:01 tonix-tuft

Hey,

This is not implemented. I could add that to the v6 roadmap

fkhadra avatar Jan 29 '20 20:01 fkhadra

Hi @fkhadra,

I have implemented this feature using pigretto (NPM package), a library I wrote which lets you intercept method calls, property access (read/write), function calls and object construction via the new keyword and do something in between (it works like a proxy).

With pigretto I've easily done the following:

// File: ./proxy/toast.js
import pigretto, { call } from "pigretto";
import { toast } from "react-toastify";

export const toastContainerId = "defaultToastContainer";

const toastContainerIdToastIdsMap = {};

const pigrettoast = pigretto(toast, [
    [
        // Intercept all the calls to a method called "success", "error", "info"
        // or a method with a name matching the `/^warn(ing)?$/` regular expression.
        ["success", "error", "info", /^warn(ing)?$/],
        // If there is a match, execute the code below (the API uses currying, still have to document it, though):
        call().around(proceed => (...params) => {
            // `params` contains the parameters passed to the called method.
            let options = params[1] || {};
            if (!Object.prototype.hasOwnProperty.call(options, "containerId")) {
                options = {
                    ...options,
                    containerId: toastContainerId
                };
                params[1] = options;
            }
            const { containerId } = options;
            toastContainerIdToastIdsMap[containerId] =
                toastContainerIdToastIdsMap[containerId] || {};

            // `proceed` here proceeds with the call of the original "success", "error",
            // "info" or "warning"/"warn" method:
            proceed(params, toastId => {
                // After the original method executes, its return value will be passed to this callback
                // (in this case the ID of the toast which was just showed).
                toastContainerIdToastIdsMap[containerId][toastId] = true;
                // We return it to the client code as well, but I could have returned anything,
                // effectively returning a completely different value to the caller
                // (which I do not want in this case, of course)...
                return toastId;
            });
        })
    ]
]);

// This is the method allowing me to close all the toasts of a container ID programmatically.
pigrettoast.dismissAllToastsOfToastContainer = containerId => {
    const toastIds = Object.keys(
        toastContainerIdToastIdsMap[containerId] || {}
    );
    for (const toastId of toastIds) {
        toast.dismiss(toastId);
        delete toastContainerIdToastIdsMap[containerId];
    }
};
export { pigrettoast as toast };

Of course, I now need to use this "patched" toast instead of the original one, so the caller code would look like this:

import { toast } from "./proxy/toast.js";

// All this toasts will be showed in the toast container
// with the ID equal to `toastContainerId` (the proxy takes care of this if I don't specify
// a different `containerId` property).
const firstToastId = toast.success("Success toast!");
toast.success("Another success toast!");
toast.error("Error toast!");
toast.warn("Warning toast!");
toast.warning("Another warning toast!");
toast.info("Info toast!");

// I can also call other methods of the `toast` object,
// they will be delegated to the original `toast` object of `react-toastify`...
toast.dismiss(firstToastId); // Dismiss the first toast.

...
// Then at some point (e.g. event handler), I can close all the toasts
// of the toast container with ID `toastContainerId` with this call:
toast.dismissAllToastsOfToastContainer(
    toastContainerId
);

Of course, this feature could be built into react-toastify itself, because it is really easy to implement, but I have handled it this way and wanted to share this solution with you.

tonix-tuft avatar Feb 20 '20 16:02 tonix-tuft

I know that this post is kind of old, but I think it still could be of general interest.

You can easily dismiss all toastrs, or one specific, o a particular set of them, in a simple manner, by wrapping your toastr text in a

with a class. Example:

toastr.options = { positionClass: 'toast-top-right' }; toastr.error('<div class="toastr">This is the text in my toastr</div>');

Since toastrs are dismissed when clicked on them, now we just have to 'click' all that has class 'toastr' to dismiss all toastrs: $('.toastr').trigger('click');

And "voilà", all toasters go. You can then fine-tune this with different classes for the div's, thereby allowing you to dismiss one toastr in particular, o a given set of them sharing the same class.

Regards

awe-eduard avatar Nov 29 '20 15:11 awe-eduard

@fkhadra You can close it if you want (or I will close it if you think it is not worth tracking anymore, let me know). I ended up monkey patching this using pigretto, as I wrote above. Would be great if react-toastify would provide this feature out of the box, though.

Thank you!

tonix-tuft avatar Dec 12 '20 14:12 tonix-tuft

I am dismissing all toast using toast.dismiss() and creating a new toast on the following line using toast.success()... It works but there is a weird jerky animation but i suspect it's because the script is not meant to be used this way. I also tried chaining the toasts like toast.dismiss().success() but this does not work.

Is there a way to dismiss a toast and replace it with a new one. Such as replacing a loading toast with a success toast. I did go through the documentation but no luck

iamjohnseun avatar Feb 10 '22 16:02 iamjohnseun

I am dismissing all toast using toast.dismiss() and creating a new toast on the following line using toast.success()... It works but there is a weird jerky animation but i suspect it's because the script is not meant to be used this way. I also tried chaining the toasts like toast.dismiss().success() but this does not work.

Is there a way to dismiss a toast and replace it with a new one. Such as replacing a loading toast with a success toast. I did go through the documentation but no luck

Side note, i am using React JS. One component creates the toast and another component is listening for an event, dismissing the toast and displaying a new toast.

iamjohnseun avatar Feb 10 '22 16:02 iamjohnseun

I am dismissing all toast using toast.dismiss() and creating a new toast on the following line using toast.success()... It works but there is a weird jerky animation but i suspect it's because the script is not meant to be used this way. I also tried chaining the toasts like toast.dismiss().success() but this does not work.

Is there a way to dismiss a toast and replace it with a new one. Such as replacing a loading toast with a success toast. I did go through the documentation but no luck

Why don't you just set a timeout after dismissing using setTimeout before showing the new success toast?

tonix-tuft avatar Feb 10 '22 16:02 tonix-tuft

That is a viable solution but i was wondering if it was something that could have been a feature.

iamjohnseun avatar Feb 10 '22 17:02 iamjohnseun

This is not implemented. I could add that to the v6 roadmap. is it added @fkhadra ? I am using v8. please confirm.

urvish91 avatar Mar 15 '22 04:03 urvish91

Same request here. I use multiple containers and want to dismiss tosts within an exact container. As an alternative is to call dismiss inside a loop over a list of known ids. But, in this case, there is a chance to notice a "stepping disappearance" animation.

Since you support multiple containers, and, the clearWaitingQueue supports passing a container id, do you have any timelines on when this feature can be implemented?

rus-yurchenko avatar Sep 08 '22 14:09 rus-yurchenko

A bit late to the party but this feature will land in v10 🎉

fkhadra avatar Jun 19 '23 19:06 fkhadra