I'm making a news site via newsapi.org api and I'm using async await to fetch the data from the API but html footer is running before async await request. How can I make my footer wait for the request to fetch , then be displayed at the bottom of the screen.
thanks in advance
function displayArticles(articles) {
let displayedArticles = articles.map((article) => {
const { title, description, url, urlToImage } = article;
return `<article >
<div >
<img src="${
!urlToImage ||
urlToImage.includes("muhtwaplus") ||
urlToImage.includes("aljazeera.net")
? "./img/No-Image-Available.jpg"
: urlToImage
}" alt= ${title}/>
</div>
<div >
<h2 >${title}</h2>
<p >${description ?? ""}</p>
</div>
<a target="_blank" href="${url}">قراءة المزيد</a>
</article>`;
});
displayedArticles = displayedArticles.join("");
document.querySelector(".main").innerHTML = displayedArticles;
}
async function createArticle(
category = "",
apiLink = "https://newsapi.org/v2/top-headlines?country=eg"
) {
const apiKey = "&apiKey=3bd4753c68144c04b3eb73e44b7da657";
document.querySelector(".main").textContent = "";
const response = await fetch(apiLink category apiKey);
const responseText = await response.json();
const articles = responseText.articles;
if (articles.length === 0)
document.querySelector(".main").innerHTML = "No data Found";
else {
displayArticles(articles);
}
}
document.addEventListener("DOMContentLoaded", function () {
createArticle();
});
<body>
<main class="main"></main>
<footer>
<p class="footer-paragraph">
Made with ❤️ in <span class="year">2021</span> by Mahmoud
Abdulmuty
</p>
</footer>
<script src="index.js"></script>
</body>;
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
A simple solution is to set your footer display to none initially and when the response is recieved set it to block or whatever it should be. Something like this:
CSS
.d-none { display: none !important }
HTML
<footer class="d-none"></footer>
Javascript after getting the response and doing what u should do
document.querySellector("footer").classList.remove("d-none");
CodePudding user response:
Before I tell you the problem I would like to tell you about how a The browser is parsing HTML when it starts loading. so whenever HTML code is loaded it's started parsing HTML code line by line and when it hits resources like img or links so it won't wait for the resources to load, in the background the resources start downloading itself, and HTML code parsing continuously until it's completed to parse the whole HTML code. so as I told you in the background when resources complete their loading then it will execute at the same when HTML is busy parsing the code.
so In js script, it loaded differently when HTML code is started parsing and whenever it hits the js script or code is starts downloading in the background but the parsing of code also has to wait until js code is loaded so when js is loaded then the parser will start parsing .
Here you are using async-await to eliminate this problem so when your code hits js code and when js see async-await the parsing of code is not waiting to load, the parser moves to the next line to execute and because of async-await code will parse code continuously without any wait. it will continue to do parsing and because of async-await it behaves asynchronously and try to execute the next line of the code so because your js code not loaded till that time because of this your footer part is executed the first.
I think probably you have to make changes in your code or try use async before src attribute <script async src="index.js"</script>
but it will really not work in many cases.
The second best choice is to use defer
before the src attribute
If you want to eliminate this type of problem you need to use 'defer' before <script defer src="index.js"</script>
and always put script tag below the end of HTML tag.
I hope you will find out more about this. Happy Coding!
CodePudding user response:
You can try putting the script before the footer I guess.