DEV Community

Cover image for How to use NASA's  APOD API
Mahesh Deshmukh
Mahesh Deshmukh

Posted on

How to use NASA's APOD API

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>

Enter fullscreen mode Exit fullscreen mode

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;
    }

Enter fullscreen mode Exit fullscreen mode

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";

Enter fullscreen mode Exit fullscreen mode

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()

Enter fullscreen mode Exit fullscreen mode

after that, you will be able to see these things in your browser console.
An image showing fetched information in browser console of NASA APOD API
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");
Enter fullscreen mode Exit fullscreen mode

We can write this new function where we will provide data as an argument.

function displaydata(data){
    }
Enter fullscreen mode Exit fullscreen mode

Inside above function. To display title

title.innerHTML=data.title;
Enter fullscreen mode Exit fullscreen mode

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=""
     } 
Enter fullscreen mode Exit fullscreen mode

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;
     }
Enter fullscreen mode Exit fullscreen mode

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>`
Enter fullscreen mode Exit fullscreen mode

To display explaination.

information.innerHTML=data.explanation
Enter fullscreen mode Exit fullscreen mode

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)
   }
 }
Enter fullscreen mode Exit fullscreen mode

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+"&";
Enter fullscreen mode Exit fullscreen mode

And fetch() will look like

 fetch(baseUrl+apiKey+newDate)
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

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();
    })
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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

Latest comments (1)

Collapse
 
adam6789 profile image
Adam Lan

This code contains so many errors, like literally typo's. This is so sloppy it's mind boggling.