DEV Community

Cover image for Building a cat image generator with Unsplash 😻
Mandi Hamza πŸ¦„
Mandi Hamza πŸ¦„

Posted on • Edited on

Building a cat image generator with Unsplash 😻

Cover image by @kivenzhao

Are you a playful learner? You should be! Play opens your mind to creativity and may help you enter a flow state. I’m new to programming so approaching learning from a playful place reduces frustration and lengthens my practice sessions.

I’m writing this post for other newbies to show them how a project can be made fun. As a newbie I love articles that include resources for further reading so I’ve made sure to include them throughout!

Before we dive into the code go ahead and click the shuffle button below to see Cats of Unsplash in action πŸ‘‡

I had three goals for this project: learn about Javascript functions, For...of loops, and keep it playful, with cats!

Plan your work. Work your plan.

A cat-image generator needs four things:

1 . A home for your code βœ”οΈ

Codepen is a popular browser based code editor that is super newbie friendly. It’s the perfect place for a project like Cats of Unsplash. Also, it has a hot reloading feature, so everytime I changed my code a new set of cat pictures appeared! This helped keep a smile on my face even when I was struggling.

2. Beautiful cat photos βœ”οΈ

Unsplash has amazing photographers who share free high-quality images. Their Unsplash Source tool serves random images and offers basic query parameters. It’s perfect for small low-traffic projects. If you're building a high-traffic app and need robust parameters you should use their free API.

3. A Little design βœ”οΈ

When I was little, I loved the bright colors Lisa Frank used. I used that as inspiration for the colorful background. I used this CSS gradient generator tool to help pick the bright colors. I love tools that make design a little easier! The images are styled using CSS grid, but I'm not going into great detail about the style because the focus for this post is Javascript.

4. Some code βœ”οΈ

The HTML markup requires 3 image elements with src tags and one button element:

<button id="shuffleButton" type="button" class="button" alt="Shuffle Button">Shuffle</button>


<div class="grid">
  <img class="cube" src="" alt="cat picture">
  <img class="cube" src="" alt="cat picture">
  <img class="cube" src="" alt="cat picture">
</div>
Enter fullscreen mode Exit fullscreen mode

We need a function to request URL responses from Unsplash. Here are the core elements:

  1. A constant to hold the URL from Unsplash Source with some parameters.
  2. A constant to hold the img elements.
  3. A constant to hold a random number generator. We’ll use it to append unique signatures to each URL request. (You'll see why we need this in a minute.)
  4. A For...of loop to iterate through the img elements and modify their src values.

First, lets declare our URL constant. This is the complete URL constant for Cats of Unsplash:

const url = "https://source.unsplash.com/collection/139386/200x200/?sig=";
Enter fullscreen mode Exit fullscreen mode

Here is a breakdown of the URL:

  1. The base URL from Unplash: https://source.unsplash.com/
  2. The collection parameter followed by the unique collection number.
    For example, I used a collection of cat images curated by @dylka.

    The URL for this collection is: https://unsplash.com/collections/139386/cats.

    We need the number for our URL: 139386

  3. The image size parameter: 200x200.

  4. The sig parameter: ?sig=.

Next, lets declare the constant that holds the img elements, like this:

const images = document.querySelectorAll("img");
Enter fullscreen mode Exit fullscreen mode

Now lets declare a constant to hold the random number generator. We’ll use it to append a unique number after the sig parameter each time we make a new request.

We need this because the browser tries to help by serving a cached copy of the URL response from Unsplash instead of a fresh response. This is usually helpful behavior, but in this case it results in duplicate images. The unique numeric signature forces the browser to make a fresh request and is otherwise ignored on the server-side. There are still occasional duplicate images, but the frequency is greatly reduced.

const randomNum = () => {
  return Math.floor(Math.random() * 1000);
};
Enter fullscreen mode Exit fullscreen mode

Now lets create a function that iterates over the img elements and populates each img src attribute value with a random Unsplash URL using the constants we declared. Here’s how the code looks:

function shufflePics() {
  for (let att of images) {
    att.src = `${url}${randomNum()}`;
    {
      console.log(att.src);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

I used a For...of loop to iterate over the img elements because it can iterate over NodeList Objects, which is what the querySelectorAll() method returns for our image constant. There are other ways to iterate over NodeList Objects, but as a beginner I find the For...of loop easy to read.

The images constant holds the image elements, but to access their src attribute values we need to use Dot Notation, like this: att.src.

Now we need to a assign the URL and randomNum constants to att.src. We wrap them like this, ${} - which is called an expression in ES6. Expressions are placeholders for the strings they contain (the URL & random number). Then the expressions are wrapped in backticks to combine them into one string.

Now, the function populates each src attribute value with a unique URL response from Unsplash. Yay! πŸ₯³

Last, we need to tie the button to the shufflePics function so it fetches three new cat pics with each click. We do this by selecting the button with the querySelector() method and adding an event listener. The code looks like this:

document.querySelector("button").addEventListener("click", shufflePics);
Enter fullscreen mode Exit fullscreen mode

That's it! Now we can shuffle endlessly through the cat pics from this Unsplash collection!

Next time you begin a tutorial or side project, I invite you to be playful! It will open your mind to new possibilities and, if you’re anything like me, it will help keep you focused.

Making Cats of Unsplash was super fun and I can’t wait to improve it! I'm excited to learn how to use Unsplash’s API so my next iteration displays the credits for the wonderful photographers.

Thank you for reading my very first Dev.to post! I look forward to your feedback about my code, our cat overlords, and how you incorporate playfulness into your work.

-Mandi Hamza

Feel free to give me shout on Twitter!

P.S. Not a cat person? Try Dogs of Unsplash 🐢

As promised, here are some resources for further reading.

This tutorial by Sheelah Brennan helped get me going on this project. I highly recommend checking it out!
β€’ ✨How to Automate Pulling in Random Images from Unsplash for Prototypes.✨

Understanding For...of Loops
β€’ 5 ways to loop over DOM elements from querySelectorAll in JavaScript
β€’ Moz documentation on Loops and iteration

Understanding template literal syntax
β€’ A guide to Javascript template literals by Flavio Copes
β€’ Template strings by Wes bos
β€’ Moz documentation on template literals
β€’ Switching to ES6 (Part 2: String Interpolation and Template Literals)

Understanding const vs. var vs. let
β€’ How let and const are scoped in JavaScript by Wes bos

Misc.
β€’ JavaScript: Arrow Functions for Beginners
β€’ Moz documentation on HTTP caching
β€’ $(document).ready() vs window.onload() vs $(window).load()

Top comments (8)

Collapse
 
nickytonline profile image
Nick Taylor

A really great explanation of all the steps. Looking forward to your next post!

Collapse
 
mandihamza profile image
Mandi Hamza πŸ¦„

Thanks, Nick!

Collapse
 
petersimnz profile image
Peter Sim

Awesome work, Mandi. I like the way you have combined a fun project with great learning resources. Keep up the good work.

Collapse
 
mandihamza profile image
Mandi Hamza πŸ¦„

Thank you, Peter! I hope it's helpful!

Collapse
 
jdorfman profile image
Justin Dorfman

Open source Fridays pay off. Great work Mandi. #waxonwaxoff

Collapse
 
mandihamza profile image
Mandi Hamza πŸ¦„

Yes, indeed! Need to get back to it soon!

Collapse
 
brunogirin profile image
Bruno Girin

Very nice article, the trick of using a random attribute to avoid caching gave me an idea for a project of mine, thanks for sharing!

Collapse
 
mandihamza profile image
Mandi Hamza πŸ¦„

Glad it sparked an idea for you!