Nasa publishes one astronomy-related picture(or videos sometimes) every day, i.e., Astronomy Picture of the Day. But do you know? That there is an API that lets you access that information, and you can make a website out of it? So I recently tried doing that, and this is what I was able to come up with.
And here are the steps so you can do it too.
1.Get your API key:
You can get your unique API key from https://api.nasa.gov/ .What you need to do is just sign up and this website will generate your API key. We will need this key to use this API which has an Hourly Limit of 1,000 requests per hour.
2.Let's get done with HTML first
There are a few things for which we want to make space in our HTML Doc. And those things are title, date picker, date(yyyy-mm-dd), copyright, image/video URL, HD URL in case of the image, explanation about image or video, and footer if you want to add your social handles or something.
so this will be our code inside the <body>
of the HTML.
<!---index.html-->
<body>
<main>
<header>
<h1>Nasa's Astronomical Picture of the Day</h1>
<form >
<label for="datepiceker">Pick a date:
<input id="datepicker" type="date" min="" max="" >
</label>
</form>
<hr style="color: white; width: 60vw;">
</header>
<section class="title-section">
<h2 id="title"></h2>
<p id="date"></p>
<small style="display: block;" id="copyright" ></small>
</section>
<section id="media-section">
</section>
<div class="description-div">
<p id="description"></p>
</div>
<script src="app.js"></script>
</body>
3.Give it your style
You can do CSS after completing the JavaScript part as well but anyway here's how I am styling this website for now.
/*style.css */
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300&display=swap');
:root{
font-family: 'Montserrat', sans-serif;
--primary-color:#171717;
}
body{
margin: 0;
background-color: var(--primary-color);
color: white;
}
header{
padding: 1rem;
}
main{
margin: auto;
text-align: center;
}
.title-section{
padding: 1rem;
}
#datepicker{
box-sizing: border-box;
width: 9rem;
padding: 00.2rem;
border-radius: 0.5rem;
}
.image-div{
width: 80%;
margin: auto;
}
#image_of_the_day{
width: 100%;
}
.video-div{
width: 80%;
margin: auto;
}
#videoLink{
width: 100%;
height: 70vh
}
.description-div{
width: 80%;
margin:0.1rem auto 1rem;
border: solid 1px white;
padding: 0.5rem;
border-radius: 00.5rem;
}
#description{
line-height:1.82;
}
3.JavaScript is waiting for you
Now, let's go step by step in this part. First, let's Just try to fetch()
data from the server for this we need two things base URL and our API key.
const baseUrl = 'https://api.nasa.gov/planetary/apod?api_key=';
const apiKey = "6qwesr0Qx97ShSYSRnRuob7OVCxeRNl9AChAJUHO";
Final URL = base URL + API key.
Now let's write a function to fetch data
function fetchData(){
try{
fetch(baseUrl+apiKey)
.then(response=>response.json())
.then(json=>{
console.log(json)
})
}catch(error){
console.log(error)
}
}
fetchData()
after that, you will be able to see these things in your browser console.
Now let's try to place this information on our website for that we can define all the HTML elements inside Javascript like this.
const title = document.querySelector("#title");
const copyright = document.querySelector("#copyright");
const mediaSection = document.querySelector("#media-section");
const information = document.querySelector("#description");
We can write this new function where we will provide data as an argument.
function displaydata(data){
}
Inside above function. To display title
title.innerHTML=data.title;
To display copyright. I noticed sometimes there is no copyright provided by the server. So we need to check whether there is copyright information available or not.
if(data.hasOwnProperty("copyright")){
copyright.innerHTML=data.copyright;
} else{
copyright.innerHTML=""
}
To display Image/video. Things would have been simpler if there is only one type of media(Image) to be handled but sometimes you have to take care of the video as well and for that, you will have to check the media type and make the decision accordingly.
if(data.media_type=="video"){
mediaSection.innerHTML=videoSection;
document.getElementById("videoLink").src=data.url;
}else{
mediaSection.innerHTML=imageSection;
document.getElementById("hdimg").href=data.hdurl;
document.getElementById("image_of_the_day").src=data.url;
}
And the imageSection and videoSection are defined as
const imageSection =`<a id="hdimg" href="" target="-blank">
<div class="image-div">
<img id="image_of_the_day" src="" alt="image-by-nasa">
</div>
</a>`
const videoSection=`<div class="video-div"> <iframe id="videoLink" src="" frameborder="0"></iframe></div>`
To display explaination.
information.innerHTML=data.explanation
Now place displaydata()
function inside the fetchdata() like this
function fetchData(){
try{
fetch(baseUrl+apiKey)
.then(response=>response.json())
.then(json=>{
console.log(json)
diplaydata(json)
})
}catch(error){
console.log(error)
}
}
Now after calling the function you should be able to see the information displayed on your webpage. Now only one thing is remaining that is to access information from past dates. To do this we have to add one additional thing to the final URL.
So, final URL = base url + api key + "&date="+"date(yyyy-mm-dd)"+"&";
And if we provide empty string in place of date then current date information will be shown.
const dateInput = document.querySelector("#datepicker");
let newDate = "&date="+dateInput.value+"&";
And fetch() will look like
fetch(baseUrl+apiKey+newDate)
You can set max and min for date picker like this. Where max date is the current date and min date is 16 June 1995 when the first picture was published.
const currentDate =new Date().toISOString().slice(0, 10);
dateInput.max=currentDate;
dateInput.min="1995-06-16";
Now we want new information to load when the date is changed so we will add an event listener to the date picker but before that create a new function named nasarequested()
and place all of the JavaScript program we have done up till now inside this new function.
function nasarequested(){
const baseUrl = 'https://api.nasa.gov/planetary/apod?api_key=';
const apiKey = "6qwesr0Qx97ShSYSRnRuob7OVCxeRNl9AChAJUHO";
const dateInput = document.querySelector("#datepicker");
const title = document.querySelector("#title");
const copyright = document.querySelector("#copyright");
const mediaSection = document.querySelector("#media-section");
const information = document.querySelector("#description");
const currentDate =new Date().toISOString().slice(0, 10);
const imageSection =`<a id="hdimg" href="" target="-blank">
<div class="image-div">
<img id="image_of_the_day" src="" alt="image-by-nasa">
</div>
</a>`
const videoSection=`<div class="video-div"> <iframe id="videoLink" src="" frameborder="0"></iframe></div>`
let newDate = "&date="+dateInput.value+"&";
function fetchData(){
try{
fetch(baseUrl+apiKey+newDate)
.then(response=> response.json())
.then(json=>{
console.log(json);
diplaydata(json)
})
}catch(error){
console.log(error)
}
}
function diplaydata(data){
title.innerHTML=data.title;
if(data.hasOwnProperty("copyright")){
copyright.innerHTML=data.copyright;
} else{
copyright.innerHTML=""
}
date.innerHTML=data.date;
dateInput.max=currentDate;
dateInput.min="1995-06-16";
if(data.media_type=="video"){
mediaSection.innerHTML=videoSection;
document.getElementById("videoLink").src=data.url;
}else{
mediaSection.innerHTML=imageSection;
document.getElementById("hdimg").href=data.hdurl;
document.getElementById("image_of_the_day").src=data.url;
}
information.innerHTML=data.explanation
}
fetchData();
}
Now add an event listener to the date picker and place nasarequested()
inside it.
const dateInput = document.querySelector("#datepicker");
dateInput.addEventListener('change',(e)=>{
e.preventDefault();
nasarequested();
})
but we want the nasarequested()
function to load before any change occurred to the date picker as well. So adding this little line of code, in the end, will help in that case.
nasarequested().onload;
Final thoughts
So, after doing all of this I hope you can also have your own Astronomical picture of the day website.
Add your style to it and please share the end result with me as well. Here are my social handles:twitter linkedin github
Refrences
1.https://sophiali.dev/javascript-fetch-api-with-nasa-api
2.https://www.youtube.com/watch?v=Y1n2a7YxYGY
Cover image credit: Jheison Huerta
Top comments (1)
This code contains so many errors, like literally typo's. This is so sloppy it's mind boggling.