diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..384a8ba Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index 255ab44..ace5fe6 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,25 @@ # 🚀 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... -``` +_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._ + +
+ +## Tech Used + +HTML, CSS, JavaScript, Openweather and Nasa APIs. + +
+ + + +
+ +[Rendered project here](https://godwinkamau.github.io/complex-nasa/) + +
+ +## Lessons Learned + +- Sometimes, APIs just don't work. That's when you use a cors proxy to work around the obstacles and keep on trucking. +- Using fetch api to process large amounts of information effectively +- Using promises to control the flow of the behavior. \ No newline at end of file diff --git "a/Screenshot 2025-11-10 at 6.26.19\342\200\257PM.png" "b/Screenshot 2025-11-10 at 6.26.19\342\200\257PM.png" new file mode 100644 index 0000000..738a499 Binary files /dev/null and "b/Screenshot 2025-11-10 at 6.26.19\342\200\257PM.png" differ diff --git a/css/pexels-spacex-60126.jpg b/css/pexels-spacex-60126.jpg new file mode 100644 index 0000000..8dd617a Binary files /dev/null and b/css/pexels-spacex-60126.jpg differ diff --git a/css/styles.css b/css/styles.css new file mode 100644 index 0000000..b231fa7 --- /dev/null +++ b/css/styles.css @@ -0,0 +1,95 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} + +.banner { + width:100%; + height:300px; + background: rgb(0, 0, 166); + color:white; + text-align: center; + display: flex; + flex-direction: column; + gap: 15px; + align-items: center; + justify-content: center; + padding:0 15px; +} + +.words { + max-width:80%; + text-shadow: 1px 1px 1px black; +} + +button { + padding:12px; + background-color: azure; +} + +.banner p{ + font-size: 2rem; +} + +table { + margin:10px auto; + background-color: rgba(255,255,255,.5); + border-collapse: collapse; +} + +td{ + padding:10px; + border:1px solid black; +} + +img { + position: fixed; + top:0; + left:0; + z-index: -1; + object-fit: cover; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..74c80ae --- /dev/null +++ b/index.html @@ -0,0 +1,21 @@ + + + + + + Nasa Facility Info + + + + + + picture of a rocket,probably spaceX + + + + \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..fcf46cf --- /dev/null +++ b/js/main.js @@ -0,0 +1,145 @@ +///////// INTRO TO MY ISSUE: I've made this object in the doxxNasa function, but I'm having trouble calling the weather list after I pass it to the next function. I've put a console.log so you can see the object after its made. + +const apiKey = 'ae194c9fd4f9c372a84ee9d9568b0d6f' + +document.querySelector('button').addEventListener('click',doxxNasa) + +//making the object +function doxxNasa() { + let centers = {} + fetch('https://corsproxy.io/?url=https://data.nasa.gov/docs/legacy/gvk9-iz74.json') + .then(res => res.json()) + .then(data => { + // organize the data received into an object, minimizing the amount of calls later on + + + data.forEach(point => { + ////consolidate the facilities into their respective centers + // initialize new key value pair if the center is not in object + if (!Object.keys(centers).includes(point.center)){ + + // add the location and facilities list upon initialization(courtesy of Michael Kazin) + centers[point.center] = {facilities : [],location:point.location} + centers[point.center].facilities.push(point.facility) + + + } else { + + // add facility to the list of facilities in the specific location + centers[point.center].facilities.push(point.facility) + + } + }) + findWeather(centers) + + + // makeTable(centers) + }) + .catch(err=>console.log(err)) + +} + +function findWeather(centers) { + //Had to cave in to chatGPT to learn about promises, I needed that information to properly form the object without running into undefined errors + // Create an array of promises + const weatherPromises = Object.values(centers).map(value => { + return fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${value.location.latitude}&lon=${value.location.longitude}&units=imperial&appid=${apiKey}`) + .then(res => res.json()) + .then(data => { + value.location.city = data.name; + value.location.temp = data.main.temp; + value.location.weather = data.weather[0].description; + }) + .catch(err => console.log(err)); + }); + + // Wait for all weather fetches to complete + Promise.all(weatherPromises) + .then(() => { + makeTable(centers); + }); +} + + +function makeTable(centers) { + console.log(centers['Kennedy Space Center'].location.city) + // console.log('Centers',centers) +//// THIS IS WHERE MY TROUBLE STARTS ///////// +//I'm trying to call the weather object's list, but I keep getting undefined + if (document.getElementById('table')) { + let deleteTable = document.getElementById('table') + deleteTable.parentNode.removeChild(deleteTable) + } + + let table = document.createElement('table') + table.id = 'table' + + + for (const[key,value] of Object.entries(centers)) { + // console.log([key,value]) + value.facilities.forEach(facility => { + // console.log(facility) + let row = table.insertRow() + + for (let i = 0; i<5 ; i++) { + const newCell = row.insertCell() + if (i==0){ + newCell.textContent = facility + } else if(i===1) { + newCell.textContent = key + } else if (i ===2) { + newCell.textContent = value.location.city + } else if (i === 3) { + newCell.textContent = value.location.weather + } else if (i === 4) { + newCell.textContent = value.location.temp + } + } + + + } + ) + + } + document.body.appendChild(table); +} + +// centers['test1']= 'boo' + // fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${centers[point.center].location.latitude}&lon=${centers[point.center].location.longitude}&units=imperial&appid=${apiKey}`) + // .then (res => res.json()) + // .then(data => { + // // place location, temperature, and weather in the same center object + // centers['test2']='oob' + // centers[point.center].weather = {'city location' : data.name, 'temp' :data.main.temp , 'weather' : data.weather[0].description} + // }) + // .catch(err => console.log(err)) + +// const nasaUrl = `https://corsproxy.io/?url=https://data.nasa.gov/docs/legacy/gvk9-iz74.json` + +// const facilities = document.querySelector('#facilities') +// const loc = document.querySelector('#location') + +// // i did have trouble using async syntax and for loops, so i applied hector's strategy of using the basic fetch syntax + +// fetch(nasaUrl) +// .then(res => res.json()) // parse response as JSON +// .then(nasaData => { +// nasaData.forEach((x, i) => { +// const lat = nasaData[i].location.latitude +// const lon = nasaData[i].location.longitude +// const weatherUrl = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&APPID=0e904a2a7aacc8772e00052c29bf80c8`; +// fetch(weatherUrl) +// .then(res => res.json()) // parse response as JSON +// .then(weatherData => { + +// facilities.innerHTML += ` ${nasaData[i].facility} || ${lat} ${lon} || Temp: ${(((weatherData.main.temp - 273.15) * 1.8) + 32).toFixed(1)} F | Humidity: ${weatherData.main.humidity} | Sky: ${weatherData.weather[0].description}` + +// }) +// .catch(err => { +// console.log(`error ${err}`) +// }); +// }) +// }) +// .catch(err => { +// console.log(`error ${err}`) +// }); \ No newline at end of file