Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added NASAfacilityproject.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 17 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
# 🚀 Project: Complex NASA API

### Goal: Use NASA's API to return all of their facility locations (~400). Display the name of the facility, its location, and the weather at the facility currently.

### How to submit your code for review:

- Fork and clone this repo
- Create a new branch called answer
- Checkout answer branch
- Push to your fork
- Issue a pull request
- Your pull request description should contain the following:
- (1 to 5 no 3) I completed the challenge
- (1 to 5 no 3) I feel good about my code
- Anything specific on which you want feedback!

Example:
```
I completed the challenge: 5
I feel good about my code: 4
I'm not sure if my constructors are setup cleanly...
```
# Complex NASA Project

This project shows NASA facility locations, names, and weather reports!

## How It's Made:

**Tech used:** HTML, CSS, and JavaScript

I used html for the markup, css for the styling, andI used Javascript for the logic of this project.

## Lessons Learned:

I learned how to interact 2 APIs to return multiple results in a single output. I also learned more about dom manipulation with grabbing data from multiple APIs and turn that data into HTML elements.

## Image of Project:

![NASAfacilityproject image](NASAfacilityproject.jpg)
17 changes: 17 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Complex nasa Project</title>
</head>
<body>
<h1>NASA Facilities</h1>

<ul id="facilities-list"></ul>


<script src="script.js"></script>
</body>
</html>
90 changes: 90 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
get the api
proxy the url api to bypass CORS

get the location of the facilities, weather, and location

loop through all facilities and render cards for each
- use long and lat in the weather API

*/

const proxyUrl = 'https://api.allorigins.win/raw?url=https://data.nasa.gov/docs/legacy/gvk9-iz74.json';

function getLocation(item) {
const city = item.city || '';
const state = item.state || '';
const zip = item.zipcode || '';

let locationStr = '';
if (city) {
locationStr += city;
}
if (state) {
locationStr += (locationStr ? ', ' : '') + state;
}
if (zip) {
locationStr += (locationStr ? ' ' : '') + zip;
}
if (!locationStr && item.location) {
locationStr = `${item.location.latitude || ''}, ${item.location.longitude || ''}`;
}
return locationStr || 'Location unavailable';
}


async function loadWeather(lat, lon, element) {
try {
const weatherUrl = `https://wttr.in/${lat},${lon}?format=j1`;
const response = await fetch(weatherUrl);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const weatherData = await response.json();
const temp = weatherData.current_condition[0].temp_F;
const desc = weatherData.current_condition[0].weatherDesc[0].value;
element.textContent = `Weather: ${temp}°F, ${desc}`;
} catch (error) {
console.error('Weather fetch error:', error);
element.textContent = 'Weather: Unavailable';
}
}

// fetch the api proxxy url
fetch(proxyUrl)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('total in dataset:', data.length);
console.log('All records:', data);

const list = document.getElementById('facilities-list');
// loop over each item and create an element for each item and then put in the html
data.forEach(item => {
const li = document.createElement('li');
const facilityName = `${item.center || ''} ${item.facility || ''}`.trim() || 'Unknown Facility';
const locationStr = getLocation(item);
li.innerHTML = `
<h3>${facilityName}</h3>
<br>
<p>Location: ${locationStr}</p>
<p>Weather: Loading...</p>
`;
list.appendChild(li);

// Load weather asynchronously
if (item.location && item.location.latitude && item.location.longitude) {
const weatherP = li.querySelector('p:last-child');
loadWeather(item.location.latitude, item.location.longitude, weatherP);
} else {
li.querySelector('p:last-child').textContent = 'Weather: Location data unavailable';
}
})
})
.catch(error => {
console.error('Fetch error:', error)
})
86 changes: 86 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
background-color: #0a0a0a;
color: #ffffff;
padding: 20px;
line-height: 1.6;
}

h1 {
text-align: center;
color: #28ae81;
font-size: 2.5em;
margin-bottom: 30px;
text-shadow: 0 0 10px rgba(0, 191, 255, 0.5);
}

#facilities-list {
list-style: none;
padding: 0;
max-width: 800px;
margin: 0 auto;
}

#facilities-list li {
background: linear-gradient(135deg, #1a1a2e, #16213e);
border: 1px solid #00bfff;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 4px 8px rgba(0, 191, 255, 0.2);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}

#facilities-list li:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 191, 255, 0.3);
}

h3 {
color: #ffffff;
font-size: 1.5em;
margin: 0 0 10px 0;
text-align: center;
border-bottom: 2px solid #00bfff;
padding-bottom: 5px;
}


p {
margin: 10px 0;
font-size: 1em;
}


p:first-of-type {
font-weight: bold;
color: #00ff7f;
}


p:last-of-type {
color: #ffd700;
font-style: italic;
}



/* responsive design! */
@media (max-width: 600px) {
body {
padding: 10px;
}

h1 {
font-size: 2em;
}

#facilities-list li {
padding: 15px;
}
}