Image Search Abstraction Layer (FCC Speedrun Project #11)

In which I somehow managed to get everything mostly working.

Abigail (agathalynn)
Chingu FCC Speedrun
6 min readMay 7, 2017

--

I like Chrome… but sometimes Firefox is Awesome.

Reflections

My last project, the Twitch.tv client, showed me how much I have learned so far during the FCC Speedrun Challenge.

This project showed me how far I still have to go.

Even the name of this project confused me at first. The idea is to be able to search for images (I used Google’s Custom Search API) that match a term passed in by the user, and then to return a subset of those results to the user in JSON format.

The “abstraction” part comes from the fact that I take care of the behind-the-scenes details you don’t care about. Instead of having to deal with Google’s API, or sifting through lots of irrelevant details in the results, you can go through me. All you have to do is tell me what you want to see images about (“unicorns and rhinoceri, please”), and what page of results you want, and we’re off.

Oh — and you can see information about recent search terms. Which means I need a database, and all the complexity that implies.

In the end, there are things in this project that I’m proud of, and many more things that I’m certain could be done better. I just don’t know how yet.

The Good:

In may ways, this challenge was easier than the previous API projects. There were so many things I had already learned:

I had already learned how to set up an express server:

I had already learned to use environmental variables and to make server-side API requests — that’s how I got location and weather information while doing my Weather App:

I had already learned how to get information into and out of a MongoDB database — that’s how I stored URL redirects in the URL Shortener API project:

I had already learned how to work with promises — on several projects, but most recently in the Twitch.tv client:

Three weeks ago, when I started this challenge, those things were all unfamiliar. By the time I got to this project, they weren’t. They weren’t easy, necessarily — that will take time and practice — but I at least knew how to start.

The Hard:

On the other hand, there are also a great many things that I still don’t know how to do, or know that I’m not doing correctly. Especially when it comes to using MongoDB:

I don’t know how to set up a new database collection.

For this project, I needed to store, access, and update information about recent searches. I used a document (in a database collection) that contains an array of recent search terms.

I wrote a function to access and update this document — but it only works if the document already exists and already contains an array of recent search results. If the document doesn’t exist, or if the latest field doesn’t exist… then stuff breaks.

So how do I make sure that the document exists?

I’m sure there’s a right way to do this. I just don’t know what it is. The solution that I’ve implemented... isn’t great. And that’s kind of an understatement.

Every time I run node app.js, I empty the entire collection in the database, and then add in a (blank) entry:

Remove everything. Insert a document with an empty array.

Does it work? Sure. As long as you don’t mind losing all your data every time you restart the server. But the whole point of storing things in a database is that you probably do mind losing your data.

I have thought of — but not implement ed— a sort of workaround: When I start my server, I could (1) check whether the collection is empty, and (2) if it is empty, insert my blank entry. I could even move that code into a separate file — a sort of “database init” program — that I only run when I actually want to erase everything in storage.

Maybe that’s even the right way to do things. Or maybe there’s a different ‘right’ solution. That’s something I have to find out.

I don’t know the best way to update items in my database.

Right now, I’m using a three-step process to update the document containing my array of recent searches:

  1. I’m using findOne to get the document out of storage
  2. I’m grabbing the array of recent searches, popping off the oldest one off the back, then unshifting the newest onto the front.
  3. I’m using updateOne to replace the old version of the array with my updated version.

Does it work? Yes. But it sure seems like there ought to be a simpler method. Maybe there’s a way to use findAndModify to pop and unshift elements from an array? And I just haven’t figured it out?

New Things

Still, every project I’ve done so far has included its share of small successes, and this one was no exception.

When I first started working with Express, I was confused by the fact that typing the URL request into my browser actually resulted in two GET requests. By this project, I was tired of seeing messages in my console telling me about requests for /favicon.ico. So I added an icon:

Note the magnifying glass.

I also started thinking about how to avoid making unnecessary API requests during the development process. Since Google’s Custom Search API limits the number of API requests you make in a day, I created a getFakeSearchResults function that returns fake results. I then used that function while I was getting the database up and running:

Commented out here.

And I learned how to tell JSHint that I’m using ES6 on purpose — which has led to a substantial reduction in the number of little yellow warning dots in my code:

:-)

Small successes.

Closing Thoughts

I have just one more project I’m going to try to knock out during Phase 1 of the FCC Speedrun Challenge — the File Metadata Microservice API project.

And then after the challenge, I think I’ll slow down and take another look at some of the difficulties that I’m skipping over here. The Speedrun has been a great way to overcome the whole deer-in-the-headlights, don’t-know-where-to-start problem, and it’s kept me from getting sidetracked or bogged down in largely irrelevant minutiae. But I’m looking forward to the opportunity to go back through these posts and deepen the knowledge that I’ve gained.

(No live demo. Code for this project is HERE.)

Next up: File Metadata Microservice.

--

--