JS 102: Mars Rover Dashboard

I’m taking the Udacity Intermediate JavaScript Nanodegree course. This is my third Udacity course, and one thing I wish I’d done in previous lessons is journaling and documenting my thought process as I work on implementing the concepts I’ve learned!

For this project, I will be using the NASA API to create a dashboard for visitors to select which rover’s data they’d like to view. The data will include images taken from that rover, information about its mission, and a way to switch between rovers. The idea of this project is to make use of the ImmutableJS library and utilize functional programming concepts to build the dashboard.

Steps/planning

I’ll start by saying I feel over my head in this project immediately. But that’s the point.

First, I need to set everything up, including the API key and environment, since this is a bit more complicated than the last project. Once that’s set and I confirm the environment is working, I need to:

  • Make my way around the API.
    • What data is included?
    • What data do I need? (Rover name, images, etc.)
    • Make sure I’m properly pulling the data before displaying it on the front-end.
  • Display the data for one specific rover to the website.
    • Create the related “page.”
    • Make sure all the desired data shows on the page using the DOM.
  • Once that’s working, expand to allow visitors to change rovers.
    • This will require adding tabs to the homepage.
    • Setting an event listener to pull and refresh the data on the page, according to the rover and date selected.
  • Final touches:
    • Ensure the project is responsive and adapts to various screen sizes.

Part of this project includes using the ImmutableJS library, particularly for managing data using persistent data structures. It seems like this will be most applicable for storing and calling the API data, to help make the program more efficient and flexible.

Day 1:

Set up the local environment and tested that it’s working as expected. Installed ImmutableJS and added dependency. Reviewed the NASA API documentation to figure out how it works and which data is available to me.

I’m using the Mars Rover Photos endpoint. It includes photos from three rovers on Mars: Curiosity, Opportunity, and Spirit. Each rover’s photos can be queried separately according to the date (on Mars) they were taken. Relevant parameters:

  • name
  • launch_date
  • landing_date
  • status
  • max_date (most recent Earth date on which photos exist)

I can filter by camera, as well, but this project requires a gallery of images, so I think it’s best to just show them all. I was able to set up two test API calls to make sure the structure was correct, and it was! Next, I want to move these over into two separate functions, since the endpoints for the rover data and the rover photos are different. Then, I’ll be better able to use the related data and variables to help filter the information.

Day 2:

Today, I knew I wanted to dig into getting the actual data from the results. Meaning, how to return the actual name of the rover or the image URLs themselves.

I got stuck because I wasn’t fully understanding the structure and use of await... then in the code. I mistakenly started trying to create an object to store the data that I knew I’d want to use, but also logically knew I wouldn’t be able to get that data out easily to use elsewhere.

With some pair programming, I moved that task into another .then statement and stored all of the data related to the rover’s manifest in a much cleaner and more accessible way. I then used the same logic to get the photos for the rover. However, the photos are stored in a nested structure – which is a whole separate logic to jump through.

That’s where ImmutableJS came in. I started by creating a map of the results, but then that wasn’t really the structure I needed for the type of data I’m storing because I wasn’t able to easily access to key and value within each object being returned. Instead, I switched to using List, and I’m now getting a return of all the image URLs in the array. (I’m still just getting this for one rover so far, Curiosity.)

Day 3:

Day 3 was slow. I was mostly trying to find my way around switching from server-side to client-side code, and navigating the starter code, too. As I started to work on writing the API call so I could show the rover manifest data on the homepage, I started getting the following error:

Uncaught ReferenceError: require is not defined

At some point, I somehow added a new requirement/library that is Node-based to the client-side JS file. 😐 It took me a while to figure out that wasn’t actually part of the starter code, and I have no idea what I was doing to paste it there. So that was fun.

With that out of the way, I set up the first API call for the rover manifest data on the user-facing site. My initial thought process is that I would then render the data from that API call on the front-end to test, but I kept getting undefined as a result because the data wasn’t actually being parsed. That said, I know my next steps for tomorrow.

/ I lost my notes from days 4 and 5, so I’m skipping right to 6. 😦

Day 6:

I already had the photos working on the site, so my next step was to create a menu and links to act as an event listener that would allow me to pass in the rover names as variables. I started confidently, working on adding the links to the site and adding those via a function. I did something I frequently do when I feel challenged, and started working on something that felt more comfortable and familiar: the layout/CSS for the site, instead of tackling the next steps.

With that tendency under control, I first added the rover name as a parameter that could be passed into the API call on the backend. I already did this with the data for the images, so I had a rough idea of how to do this. Then, I set up the links on the front-end, so I could pull each rover name by an event listener. With that set up, I was able to use an existing method to update the store bypassing in the element that was selected.

I had a little trouble getting it to render on the page since I knew the information was being passed, but I wasn’t actually getting it to render because I missed updating a variable in a separate function. All in all, while it was challenging to get started and figure out the next steps, this felt like a pretty straightforward process. I’m planning to do the same thing for the photos tomorrow by adding the rover name as a parameter there, as well, so clicking on the link updates the photos, too.

Thinking ahead to the future and knowing the requirements of this project, I still haven’t used ImmutableJS at all. Instead, I’ve been focusing on doing what I already know, and I figure I’ll refactor later to meet that requirement. That said, it occurred to me that I can use this library for updating store, so I’m keeping that in mind.

Day 7:

Today was tough, mostly because I was exhausted by the time I came to the project. I was able to use most of the same logic/format that I used to filter the rover information by rover name with the photos. One of the unique elements here is that I needed to add multiple parameters to the backend, which was new-ish, but pretty easy in Express.

On the front-end, I really struggled – as usual – with following the flow of data and making sure I was passing all the correct parameters. Once I got that working, I was able to focus on creating and using a “date” input to filter photos as well. (And added a bit of “error handling,” if you can call it that, when there are no photos for a specific date.)

It may sound silly, but one of the most exciting parts was adding a second event handler to automatically update the photos when a new date is selected. I needed to switch to a different option – since automatically updating was making it impossible to actually select a new date – but it’s so satisfying to see the change on the front end.

The last hurdle I tackled was actually simpler than it seemed. Because of how Express handles static files, I was having a hard time adding my CSS to the index.html file. After a few false starts and reviewing the existing code, I literally was just missing a forward slash.

Day 8:

In this last session, I added some CSS just to make the site look more like I had in mind. I also added in some CSS for a spinner – rather than just showing loading... while the calls are made, and I worked on adding a library to display the photos in a gallery.

I spent most of my time refactoring the gallery code to work with what I’ve written. Where I ended today, I was able to start displaying the photos within the gallery. However, the logic/math to show only eight photos at a time isn’t working just yet, and I’m not sure why. I’m taking a break before coming back since I’m unable to see what’s causing the issue.

Once that’s resolved, I want to work on fixing the CSS for the spinners and then refactoring some more to use ImmutableJS.

Day 9:

It’s been a busy week, so I haven’t spent as much time on this consistently. However, I picked back up on refactoring the gallery code that I was using and was able to get the filtering working properly. I also added in navigation, both via buttons and the keyboard, which was much easier once I had the initial logic down for how to navigate through the pages.

Another somewhat simple fix was updating the spinner for when the photos are loading. With the image gallery working, the two main next steps are:

  • Refactor the code to use ImmutableJS with store
  • Adjust CSS so the site is mobile-friendly

Day 10:

Today, I focused on adding in the ImmutableJs library, so I could meet that requirement. To be honest, I wasn’t wild about this since I feel like its implementation was a little forced for this application in particular, but it was helpful to practice. In particular, I got to make use of the Map(), toObject(), and merge() methods, all of which are new for me.

In this case, I was able to update the project so that the store is wrapped in an anonymous function, and then I use ImmutableJS methods to set and update the store throughout the application. The hardest part, honestly, was wrapping my head around the best way to use ImmutableJS in this particular instance. Refactoring everything after was surprisingly straightforward – I only ran into one bug where my function was expecting an object, but Immutable doesn’t return objects, just key: value pairs. Fortunately, there’s also a method built in to do just that.

All in all, I actually felt pretty good about the work today.

Last Day:

All in all, this project took me about a month, but with breaks in between. (Hello end-of-year!) For this last session, I focused on:

  • Implementing a hamburger menu via CSS for a more responsive design
  • Fighting with ESLint to standardize my code in my editor

This project was humbling in that I really thought I understood CSS well, and I see now that I know how to tinker in CSS pretty well – but I don’t know the standards and rules. I had to revisit a lot of concepts, like how to use grid and flex layouts, as well as making better use of pseudo-classes. Originally, I was planning to use JavaScript to implement the mobile menu, but I’m much happier with this option.

Finally, I wanted to make sure everything was standardized and clean. I had added a different JS linter to my code editor already, and it wasn’t accepting the rules/standards I wanted. I likely spent more time struggling to set up what I wanted – and make sure the old extension I was using was disabled – than actually fixing the code to match the rules.

I finally submitted my project shortly after! So now I’m just waiting for feedback. Update: it was accepted!

Helpful resources

Leave your two cents here:

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: