NASA Photo of the Day API

Space ring with a turquoise glow surrounded by stars. Built for front end development experimentation.

The NASA Photo of the Day API, (dubbed APOD Nasa Gov), is a neat endpoint. It outputs photographic urls and descriptions for any given date. Dates extend as far back as 1995. Development aside, I think it’s absolutely amazing any individual with rudimentary programming skills can tap into NASA’s data archives. Programming skills can be in any one of a variety of languages. One simply needs the ability to perform a GET request in their most comfortable language.

Git Repo

This is an app written in TypeScript with a little bit of RxJS. It consists of a header component displaying the photo title and date. The date is derived from the date picker component which sends it to a service. Observers listen to updates in the header, main photo component, and sidebar. All of which are wrapped in a parent component. Change month and year in the date picker by clicking on either. Click anywhere outside the UI to see the history in the console.

Though the endpoint primarily outputs photos, sporadically it supplies a video. Which is handled accordingly, enabling the UI to play an array of videos from Mars, galaxies, and other far away places. There’s a number of ways the UI could be designed to accommodate date selection and data display. This elementary layout certainly achieves the goal, responsively. Cycle through dates.

App Component

In this rudimentary NASA Photo of the Day app, we have the header, body, and search components shown below. The header click event simply closes the date picker. As does the body external click event. The outputData event outputs the history. There’s no need for routing. But, the date is being appended to the URL. This occurs in the service (nasa.service.ts) at line 64.

<div id="nasa-pod" class="element-shadow">
  <nasa-pod-header (click)="externalClick()"></nasa-pod-header>
  <main>
    <div
      nasa-photo-body
      (outputData)="searchResults($event)"
      class="column-data"
      (click)="externalClick()"
    >
      <div class="photo"></div>
      <p>Photo description ...</p>
    </div>
    <div nasa-search class="column-search"></div>
  </main>
</div>

The router and module don’t have anything particularly unique in them. They’re both very conventional. Regardless, both are shown below. They could actually be combined into one file for simplicity. I only did it this way because I’m accustomed to preparing everything I build for a production grade application. In which, we’d certainly have a robust router. Moreover, the module uses WindowRef as a provider simply to obtain the Window object. This is used for dynamic responsive control.

import { NgModule } from "@angular/core";
import { PreloadAllModules, RouterModule, Routes } from "@angular/router";
import { NasaPhotoBodyComponent } from "./components/photo-body/photo-body.component";

const routes: Routes = [
  { path: "apod", component: NasaPhotoBodyComponent },
  { path: "**", redirectTo: "apod" },
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }),
  ],
  exports: [RouterModule],
})
export class AppRoutingModule {}

export const appRoutingComponents = [NasaPhotoBodyComponent];
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { AppComponent } from "./app.component";
import { CalendarComponent } from "./components/date-picker/date-picker.component";
import { HttpClientModule } from "@angular/common/http";
import { WindowRef } from "./windowRef";
import { NasaHeaderComponent } from "./components/header/header.component";
import { NasaSearchComponent } from "./components/seachbar/search.component";
import { AppRoutingModule, appRoutingComponents } from "./app-routing.module";
import { YouTubePlayerModule } from "@angular/youtube-player";

@NgModule({
  declarations: [
    AppComponent,
    CalendarComponent,
    appRoutingComponents,
    NasaHeaderComponent,
    NasaSearchComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    YouTubePlayerModule,
    AppRoutingModule,
  ],
  providers: [WindowRef],
  bootstrap: [AppComponent],
})
export class AppModule {}

Other Components

As previously explained we have four components. The date picker has a post of it’s own so I won’t cover that here. The photoBody has very basic Angular directives. For even remedial developers, this should look pretty basic. But shall you have questions, please free to leave a comment or question. I’ll be happy to explain whatever you need. You can view the photoBody TypeScript here. The other two components are massively simple. The search bar is nearly empty, but is an ideal location to pull the cache and display previously viewed imagery. Header component only contains the date, which is obtained from @input & @output.

<div class="photo-body">
  <button type="text" (click)="showText()">
    {{ fullExplanation && !datePickerStatus ? "Hide " : "Show " }}Details
  </button>
  <div
    class="hd-url"
    [ngStyle]="{ 'background-image': getUrl() }"
    (click)="closeCalendar()"
    *ngIf="mediaType! === 'image'"
  ></div>
  <div class="video-wrapper" *ngIf="mediaType! === 'video'">
    <youtube-player videoId="{{ videoURL }}"></youtube-player>
  </div>
  <div class="explanation" *ngIf="fullExplanation && !datePickerStatus">
    {{ explanation }}
  </div>
</div>

APOD Nasa Gov Payload

The payload is basic as well. In my app, I chose to include only the explanation in the UI. But, I’m certainly using the hdurl. Granted I could’ve used the url instead. Perhaps this would increase speed/ performance. IDK. I didn’t test the difference, and loading time is always quick. The image tag uses a dynamic url. I’m also using the media_type in the code.

The header incorporates the title value. I could utilize the date, but it’s already displayed from the date picker component. I was happy to see the payload is very straightforward. Making it easy to disperse data wherever I need it. No need for double loops or dealing with nested arrays. This is as basic a payload as we can hope for.

{
    "copyright": "\nBray Falls & \nChester Hall-Fernandez\n",
    "date": "2023-08-22",
    "explanation": "This nebula had never been noted before. Newly discovered...",
    "hdurl": "https://apod.nasa.gov/apod/image/2308/Pistachio_Falls_2952.jpg",
    "media_type": "image",
    "service_version": "v1",
    "title": "The Pistachio Nebula",
    "url": "https://apod.nasa.gov/apod/image/2308/Pistachio_Falls_960.jpg"
}

In conclusion, and perhaps most importantly, visit the NASA API page and get yourself a key. Then plug it into the key value located in the environments file. This will get you up and running. Moreover, check out additional projects just like this one. If you’re looking for API powered ones, this is a good one. As is this project too. Otherwise, I hope you can easily clone this project and get it working without a hitch. Leave a comment if you have questions on my NASA Photo of the Day app.

2 Comments

  1. I needed to draft you one little remark so as to thank you the moment again regarding the remarkable techniques you have featured in this case. It was so generous of you to grant publicly just what a lot of folks would have supplied as an ebook to generate some profit for their own end, mostly seeing that you could have done it in the event you considered necessary. The techniques likewise worked to become fantastic way to fully grasp other people have the identical zeal like my own to learn great deal more when it comes to this condition. I think there are a lot more fun sessions in the future for individuals that find out your blog.

1 Trackback / Pingback

  1. Open Weather Map API - Frontend Development

Leave a Reply

Your email address will not be published.


*