Reputation: 33
I am using render.com to deploy my dynamic websites and have opted to use their free tier. Render will spin down the free web service after 15 minutes of inactivity and spin the service back up whenever it next receives a request to process. However, spinning up a service from idle takes quite a bit of time, causing a noticeable delay for incoming requests until the service is back up and running. The result is that the browser page load will hang momentarily.
To make the experience more user friendly I decided to create a preloader animation that shows up while the server is spinning up from idle (using fetch). However, my current code only works after the server has been spun up. I am clearly doing something wrong but am completely stumped.
Here is my current code that checks if the service is up and handles the preload animation using jQuery.
// Function to check if the service is up using async/await
async function isServiceUp() {
try {
const response = await fetch("https://cookyourkitchen.onrender.com");
console.log(response);
} catch (error) {
console.error('Error checking service status:', error);
return false; // Service is down or unreachable
}
}
$(document).ready( () => {
if(isServiceUp){
$("#loader").fadeOut(1000);
$("#content").fadeIn(1000);
} else {
$("#loader").show();
}
});
Here is the html (ejs) that is relevant to my problem.
<body>
<div id="loader" class="loader"></div>
<div id="content" class="container">
<div class="px-4 py-5 my-4 text-center">
<h1 class="display-5 fw-bold text-body-emphasis">Cook Your Kitchen</h1>
<div class="col-lg-6 mx-auto">
<p class="lead mb-4">Have some random ingrediants in your kitchen? <br>
Those veggies about to go bad?? <br>
Enter the ingrediants you want to use and get recipe suggestions!
</p>
<form action="/search" method="post">
<div class="d-grid gap-2 d-sm-flex justify-content-sm-center">
<input type="text" id="search" name="ingrediants" class="form-control"
placeholder="Chicken, beans, tomato,..." aria-label="Recipient's username"
aria-describedby="button-addon2">
<button class="btn btn-outline-secondary" type="submit" value="Submit" id="button-addon2">Get a recipe</button>
</div>
</form>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4="
crossorigin="anonymous"></script>
<script src="preloadwebpage.js"></script>
<script src="loadrecipes.js"></script>
</body>
Upvotes: 1
Views: 732
Reputation: 133
I think I see what's going on here.
First, in your snippet, you're not calling the isServiceUp
function:
if (isServiceUp)
will always be true because your asking if a function pointer is true (function pointers are truthy). I think you meant to call it instead: if (isServiceUp())
.
Next, isServiceUp
is async, and when you call it, it returns a Promise, which is also truthy. If you want to know the outcome of the operation, you need to await
it, which means you need .ready
to be async (which jquery supports):
$(document).ready( async () => {
var isUp = await isServiceUp();
if (isUp){
$("#loader").fadeOut(1000);
$("#content").fadeIn(1000);
} else {
$("#loader").show();
}
});
That worked for me. (jsfiddle)
It's a good idea adding a spinner to wait for the render instance to spin back up. There are options to keep your free tier instance from going down in the first place if rather not jump through hoops. I wrote one that's free.
Upvotes: 0