2

I want to add loading message for export file button if it takes time to load for example first message "please wait" after 10 seconds settimeout to "loading..." after 20secound "sorry, please wait"

const [loading, setLoading] = useState(false);

function greet1() {
  return "please wait.."
}
function greet2() {
  return "loading"
}
function greet3() {
 return "sorry, please wait..."
}

const list= () => {
setLoading(true)
    if (loading) {
      setTimeout(() => {
        greet1
      }, 0);
      setTimeout(() => {
        greet2
      }, 2000);
      setTimeout(() => {
        greet3
      }, 3000);
    }
}

  • correct me if I'm wrong, but I assume you want the ability to display the message in a DOM element such as ` – Urmzd Nov 18 '21 at 22:01
  • @Urmzd, yes i want to display in a DOM – tinyVariant Nov 18 '21 at 22:14
  • You have to either call your `greet` functions like `greet1()` or drop the arrow functions `() => { }` around them. – FZs Nov 18 '21 at 22:19
  • @tinyVariant how are you exporting your file? Can I assume you mean "download" when you say load? Do you want to track the progress of the download? – Urmzd Nov 18 '21 at 22:24
  • @Urmzd, yes I want to add different message while it takes time download – tinyVariant Nov 18 '21 at 22:27
  • @tinyVariant can you tell me how you're downloading the file? Are you using a library or? – Urmzd Nov 18 '21 at 22:36
  • You have to show more code, where do you want to display your messages and how your template is structured. You can `Toast()` messages or you can pass to component. I just wanted to show how to call step by step. – flakerimi Nov 18 '21 at 23:01
  • show whole component pls – flakerimi Nov 18 '21 at 23:07

3 Answers3

0

I am not sure how is your code in React but in simple JS it works. Just tweak it for your need. Updated: added ability to write inside message div.

var message = document.getElementById("message");
function greet1() {
 message.innerHTML = "please wait..";
}
function greet2() {
   message.innerHTML= "loading";
}
function greet3() {
  message.innerHTML= "sorry, please wait...";
}
var loading = true;
    if (loading) {
      setTimeout(() => {
        greet1();
      }, 0);
      setTimeout(() => {
        greet2();
      }, 2000);
      setTimeout(() => {
        greet3();
      }, 3000);
    }
<div id="message" ></div>
flakerimi
  • 2,580
  • 3
  • 29
  • 49
  • The question is unclear. Your answer is the exact same code as the above (with the exception that your answer actually invokes the function). You're just logging the information, not "displaying" it, with what I would assume to be a DOM element. @tinyVariant please verify if this is what you wanted – Urmzd Nov 18 '21 at 22:04
  • Updated for DOM, but really same thing. – flakerimi Nov 18 '21 at 23:07
  • No it isn't. This is a `javascript` specific solution. The question has been tagged with `reactjs`. It should be using react concepts to ensure correctness. @flakerimi – Urmzd Nov 18 '21 at 23:11
0

you can write:

if (loading) {
 let time = 0;
 setTimeout(() => {
  switch(time) {
   case 2:
    alert("please wait...");
    break;
   case 5:
    alert("loading...");
    break;
   case 10:
    alert("sorry, please wait...");
    break;
  }
  time++;
 }, 1000);
}
  • Hi @mmsadati, welcome to SO! When answering a question, please take a look at [here](https://stackoverflowsolutions.com/topic/product-guides/how-to-ask-and-answer) to learn how to correctly answer questions. Don't forget to ask for clarification before giving an answer! – Urmzd Nov 18 '21 at 22:16
  • Thanks @mmsadati, but i want to display it as a dom – tinyVariant Nov 18 '21 at 22:17
0

In your specific case, you might do the following:

  1. You need to correct your syntax. Functions are invoked by using () following the namespace. E.g. greet1()
  2. Create a counter-based state (since it seems like your messages vary based on the "duration"). This allows us to determine the "time" that has passed.
const [downloadStatus, setDownloadStatus] = useState(0);
  1. Add a onClick listener to trigger the download.
const messageDownloadPairs = { 
  1: ["Message1", 0],
  2: ["Message2", 10 * 1000]
  3: ["Message3", 20 * 1000]
}
const getDownloadMessageTimePair = (status) => 
  messages[Math.min(status, Object.values(messages).length)]

with the following jsx under return

<button onClick={invokeDownload}>{getDownloadMessage(downloadStatus)[0]}</button>

where invokeDownload follows the signature

const invokeDownload = () => {
  // Your download code here.
  setDownloadStatus(1) // Notifying the component that the download has started.
}
  1. Create a function checkDownloadStatus to check if the download has completed. You can find some examples here
  2. Use the hook useEffect to handle timeouts, and state updates.
useEffect(() => { 
  const downloadComplete = checkDownloadStatus()

  if (!downloadComplete) { 
    const newDownloadStatus = downloadStatus + 1
    setTimeOut(
      () => setDownloadStatus(newDownloadStatus), 
      getDownloadMessageTimePair(downloadStatus)[1]
    )
  }
}, [downloadStatus])

With this, you have a "progress-supported" button to track your csv download. I'll update this when I get more information on the specifics of your project.

Urmzd
  • 682
  • 4
  • 17