tutorial // Jul 01, 2022

How to Generate Random Project Names with JavaScript

How to generate a random, hyphenated project name string from a list of adverbs and animals for use with user generated content.

How to Generate Random Project Names with JavaScript

For this tutorial, we're going to use CheatCode's full-stack JavaScript framework, Joystick. Joystick brings together a front-end UI framework with a Node.js back-end for building apps.

To begin, we'll want to install Joystick via NPM. Make sure you're using Node.js 16+ before installing to ensure compatibility (give this tutorial a read first if you need to learn how to install Node.js or run multiple versions on your computer):

Terminal

npm i -g @joystick.js/cli

This will install Joystick globally on your computer. Once installed, next, let's create a fresh project:

Terminal

joystick create app

After a few seconds, you will see a message logged out to cd into your new project and run joystick start:

Terminal

cd app && joystick start

After this, your app should be running and we're ready to get started.

Gathering source data

In order to generate a random project name, we'll need some random data to use as the source for names. While you can use any name you'd like, for this tutorial, we're going to source two lists from this helpful repo on Github: a list of adverbs and a list of animals. There are some other lists in that repo, too, so feel free to experiment or create your own.

Once you've picked out the lists you want to use—assuming you're using the lists from the link above—we'll want to pull them into our project and format them for use in our code. In the project we just created with joystick app, we want to create two files in the /lib folder: /lib/adverbs.js and /lib/animals.js:

/lib/adverbs.js

export default [
  'abnormally',
  'absentmindedly',
  'accidentally',
  'acidly',
  'actually',
  ...
];

/lib/animals.js

export default [
  'Aardvark',
  'African Elephant',
  'African Tree Pangolin',
  'Albatross',
  'Alligator',
  ...
];

Here, we've truncated the lists due to their length but you will want to input the full lists for your files. The two files above can be found formatted like the code blocks above here.

Once you have those files in your /lib folder, we can move on to the name generator.

Writing a name generator function

Our name generator function will have three steps to it:

  1. Picking out a random adverb and animal name from our lists.
  2. Formatting both names, shifting them to be all lowecase and replacing any spaces with - hyphens.
  3. Concatenating or joining together the lowercased, hyphenated versions into one name.

Let's take a look at the full function and step through it (it will be easier to understand as we're going to compose together function calls).

/lib/generateProjectName.js

import adverbs from "./adverbs";
import animals from "./animals";

const lowercaseAndSlugify = (string = '') => {
  return string.toLowerCase().replace(/ /g, '-').replace('--', '-').trim();
};

const getRandomArrayItem = (array = []) => {
  return array[Math.floor(Math.random() * (array.length - 1))];
};

export default () => {
  const adverb = lowercaseAndSlugify(getRandomArrayItem(adverbs));
  const animal = lowercaseAndSlugify(getRandomArrayItem(animals));
  return `${adverb}-${animal}`;
};

Starting at the top, we add two imports to our file: one for our adverbs.js file and one for our animals.js file in the same folder. Down at the bottom of our file, we add a default export of our function.

Inside, starting with our adverb, we compose together two function calls defined above of our main function. In JavaScript, function calls work similar to a math problem, evaluation from the inside first to the outside last.

Here, our innermost call is to a function getRandomArrayItem(), which, like the name implies is designed to get a random item from some array we pass it. In this case, we're passing in the adverbs list we imported up top. Looking at that getRandomArrayItem() function, we take in our array and return a line that says "select the item in the passed array at this random index array[someRandomIndex]."

To get that random index, we call to Math.random() which gives us a random number between 0 and 1 and then multiply it by the length of our array, subtracting 1. We do this because we'll get a number like 0.5121 from Math.random() which when multiplied by the length of our array, will give us a number between 0 and the length of our array (i.e., a random index of an item in that array). For example, if our array length was 25 and we got back 0.5121 from Math.random(), our final number would be 12.2904 (24 * 0.5121).

Because we want a flat integer and not a decimal or "float" number, we take the result of this multiplication and pass it to Math.floor() which will round the resulting number down to the closest whole number, or in the example above, 12. Passing this like array[12], we'd expect to get back the value at index 12 in the passed array.

Once we get back our random value, the next chunk of work we need to do to make the value usable in our project name (we're going for a name like advantageous-advark), we want to lowercase it and then replace any spaces with a -.

Above in the lowercaseAndSlugify function, we get this done by taking in the passed string as an argument and then immediately call .toLowerCase() on it, chaining a call to .replace(/ /g, '-') to say "globally in this string, replace all spaces with a - character" followed immediately by a .replace() for any accidental -- double-hyphens created from double spaces in names with a single - hyphen. Finally, we chain one last call on the end to .trim() to make sure we've eliminated any unnecessary spaces.

That's it for formatting. Back down in our exported function, we repeat this chain of events to get our animal, passing in the animals array to get a random value and format it. With both our random adverb and animal, we return a concatenated string from our function, joining the two variables together with a - hyphen using JavaScript string interpolation.

That's it for generating our name! Now, let's wire it up to our UI and put it to use.

Putting the generator to use

This part is pretty simple. To test out our function, we're going to wire up a Joystick component. To do it, we're going to replace the existing code in /ui/pages/index/index.js (this file was automatically generated when we ran joystick create app earlier) with the following:

/ui/pages/index/index.js

import ui from '@joystick.js/ui';
import generateProjectName from '../../../lib/generateProjectName';

const Index = ui.component({
  state: {
    projectName: null,
  },
  events: {
    'click button': (event, component) => {
      component.setState({ projectName: generateProjectName() });
    },
  },
  render: ({ when, state }) => {
    return `
      <div>
        <button>Generate a Project Name</button>
        ${when(state.projectName, `
          <h1>${state.projectName}</h1>
        `)}
      </div>
    `;
  },
});

export default Index;

Up top, we import the ui object from @joystick.js/ui which gives us access to the ui.component() method for creating our component along with our generateProjectName function from our /lib folder. Below this, we create our component and store it in a variable Index which is exported from our file at the bottom (this file is already wired up to the router in our app so we don't need to do anything else to make it work).

Focusing on the component itself, down in the render() function we return a string of HTML to render for our component. Inside, we return a <div></div> tag with a <button></button> and a special call to when() a function passed to the render() function of Joystick components (known as the when "render function").

That function is designed to render some HTML when some condition is met. Here, we check to see if the state.projectName value is defined. Here, state is pulled from the component instance passed to the component's render() function (the same place we plucked when() from). That state can be set by default on our component via the state property set on the object passed to ui.component().

Above, we do that by default setting projectName on state to null. In other words, when our component first loads up state.projectName is equal to null, so our call to when() down in our render() function wont' render the HTML passed as the second argument to it (our state.projectName value wrapped in an <h1></h1> tag).

To change this value, we need to call to our component's .setState() method. Here, we do that in response to a click event on the button inside of our component. Up in the events object passed to the options for ui.component(), we've defined an event listener for a click event on all button elements in our component (just one in this case).

Inside of the function passed to the listener definition click button, we expect to get the DOM event as the first argument and then the component instance as the second argument. On that component instance, we get access to a function .setState() which we can call to update values on our component's state object. To .setState() we pass an object with all of the values we want to update as properties. Here, we want to set projectName equal to a random project name, so we set it equal to a call to generateProjectName().

The end result is that now, every time we click on our button, we'll set projectName to a new random name and our when() will render that name to the screen. That's it!

Wrapping up

In this tutorial, we learned how to generate a random project name in JavaScript. We learned how to write a function that can select random values from an array as well as a function for formatting the selected random value to be all-lowercase and stringified. Next, we learned how to concatenate our random values into a single string and return them from a function. Finally, we learned how to call our function and use its value to display inside of a Joystick component.

Written By
Ryan Glover

Ryan Glover

CEO/CTO @ CheatCode