If I press Send ☞
without choosing a file, it’ll say “No file selected.” in a little Bootstrap warning alert but it seems to break all future alerts like file uploaded or file already exists on disk.
If I make an error alert like file already on disk, it’ll work and won’t break future alerts (meaning it won’t stop alerts that popup in the future from showing).
So, why is the “No file selected” alert breaking other alerts?
In this clip, you can see me trying to make more than one of that alert but it just doesn’t want to.
Here is my ejs file:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Androp</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous"> </head> <body> <div class="container-fluid"> <p> <h1>Androp - Send to [...] MBP</h1> </p> <div class="input-group mb-3"> <button class="btn btn-outline-primary" type="button" onclick="send()">Send ☞</button> <input type="file" class="form-control" id="fileSelector"> </div> <div id="alerts"></div> <div class="text-center"> <div id="spinny" class="spinner-border" style="width: 3rem; height: 3rem; visibility: hidden;"></div> </div> </div> <script src="/socket.io/socket.io.js"></script> <script> const socket = io() const engine = socket.io.engine let maxSize = 0 let sending = false socket.on("disconnect", (reason) => { alert(`Disconnected from laptop! Check your internet or refresh the page. 💀 (${reason})`, "warning") }) engine.on("close", reason => { console.log(reason) }) socket.emit("getMaxSize", (size) => { return maxSize = size }) const alert = (message, type) => { const wrapper = document.createElement('div') wrapper.innerHTML = [ `<div class="alert alert-${type} fade show" role="alert">`, ` <div>${message}</div>`, '</div>' ].join('') document.getElementById("alerts").append(wrapper) return bootstrap.Alert.getOrCreateInstance(wrapper) } function send() { if (sending) { return false } sending = true const file = document.getElementById("fileSelector").files[0] || false function close(alert) { setTimeout(() => { alert.close() }, 3500) } if (!file) { return close(alert("No files to upload.", "warning")) } if (file.size >= maxSize) { return close(alert(`File is bigger than ${Math.round(maxSize / (1024 ** 2))} MB`, "danger")) } document.getElementById("spinny").style.visibility = 'visible' socket.timeout(10000).emit("upload", file, file.name, file.size, (err, status) => { if(err) { return close(alert("Could not contact laptop within 10s, laptop might be in sleep mode. 💀", "warning")) } document.getElementById("spinny").style.visibility = 'hidden' sending = false return close(alert(status.message, status.success ? "success" : "danger")) }) } </script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.5/dist/umd/popper.min.js" integrity="sha384-Xe+8cL9oJa6tN/veChSP7q+mnSPaj5Bcu9mPX5F5xIGE0DVittaqT5lorf0EI7Vk" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.min.js" integrity="sha384-ODmDIVzN+pFdexxHEHFBQH3/9/vQ9uori45z4JjnFsRydbmQbmL5t1tQ0culUzyK" crossorigin="anonymous"></script> </body> </html>
Advertisement
Answer
You should move the flag sending = true
when you actually plan to send after validation. I would also place sending = false
right when callback returns, even if err
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Androp</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous"> </head> <body> <div class="container-fluid"> <p> <h1>Androp - Send to [...] MBP</h1> </p> <div class="input-group mb-3"> <button class="btn btn-outline-primary" type="button" onclick="send()">Send ☞</button> <input type="file" class="form-control" id="fileSelector"> </div> <div id="alerts"></div> <div class="text-center"> <div id="spinny" class="spinner-border" style="width: 3rem; height: 3rem; visibility: hidden;"></div> </div> </div> <script src="https://cdn.socket.io/4.5.0/socket.io.min.js" integrity="sha384-7EyYLQZgWBi67fBtVxw60/OWl1kjsfrPFcaU0pp0nAh+i8FD068QogUvg85Ewy1k" crossorigin="anonymous"></script> <script> const socket = io() const engine = socket.io.engine let maxSize = 0 let sending = false socket.on("disconnect", (reason) => { alert(`Disconnected from laptop! Check your internet or refresh the page. 💀 (${reason})`, "warning") }) engine.on("close", reason => { console.log(reason) }) socket.emit("getMaxSize", (size) => { return maxSize = size }) const alert = (message, type) => { const wrapper = document.createElement('div') wrapper.innerHTML = [ `<div class="alert alert-${type} fade show" role="alert">`, ` <div>${message}</div>`, '</div>' ].join('') document.getElementById("alerts").append(wrapper) return bootstrap.Alert.getOrCreateInstance(wrapper) } function send() { if (sending) { return false } const file = document.getElementById("fileSelector").files[0] || false function close(alert) { setTimeout(() => { alert.close() }, 3500) } if (!file) { return close(alert("No files to upload.", "warning")) } if (file.size >= maxSize) { return close(alert(`File is bigger than ${Math.round(maxSize / (1024 ** 2))} MB`, "danger")) } sending = true document.getElementById("spinny").style.visibility = 'visible' socket.timeout(10000).emit("upload", file, file.name, file.size, (err, status) => { if (err) { return close(alert("Could not contact laptop within 10s, laptop might be in sleep mode. 💀", "warning")) } document.getElementById("spinny").style.visibility = 'hidden' sending = false return close(alert(status.message, status.success ? "success" : "danger")) }) } </script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script> </body> </html>