Let’s Build a Random Character Generator with Faker.js! 
Tags: javascript, react
Published: 2020-10-08 18:53:49

[National Novel Writing Month](https://nanowrimo.org/) is just around the corner, and it’s a great time to start creating characters to populate your soon to be 50,000-word stories. If you’re like me, I often struggle the most when it comes to naming characters. Thankfully, [Faker.js](https://github.com/marak/Faker.js/), a random generator library, has a whole host of random names to generate. 

It’s helpful to know basic React knowledge before getting started. Check out their [documentation](https://reactjs.org/docs/getting-started.html) if you’re unfamiliar with the framework. 

# Getting Started 

In a directory of your choosing, type the following command to create a React application: 

```$ npx create-react-app character-creator```

Navigate to the project directory. 

```$ cd character-creator```

```$ npm i faker```

Finally, host the site in your web browser. 

```$ npm start```

# Setting Up the Files 

This file will have an App.js class and component named CharacterGenerator.js 

![File structure with App.js at top level and a components folder with CharacterGenerator.js inside](https://dev-to-uploads.s3.amazonaws.com/i/32ptswb9p5c0drtvr32w.png)

As App.js is at the top level, we’ll want to render our CharacterGenerator through it. 

```js
import React, { Component } from 'react'
import CharacterGenerator from './components/CharacterGenerator'
class App extends Component {
 render() {
   return (
    <div>
       <CharacterGenerator/>
     </div>
   )
 }
}
export default App
```

In the previous code, we are rendering our CharacterGenerator component through App.js 


If you haven’t already, create a components folder and within that folder create CharacterGenerator.js 

Most of the work we’ll be doing will be in this component. 

For now, set up the basic class structure. 

```js
import React, { Component } from 'react'
class CharacterGenerator extends Component{
[...]
}

```

You’ll also want to import the Faker.js library 

```import Faker from 'faker'```

# Creating Characters 

The Faker library comes with many options for adding fake data for our characters, although the intent is probably business related as opposed fiction related (more on that later). To start creating characters, we’ll add them to our state.

```js
constructor(props){
	super(props)
	this.state = {
		characters: []
	}
}

``` 

In our lifecycle method, we’ll load some characters. 

```js
componentWillMount() {
       for (let i = 0; i < 5; i++) {
           const character = {
             firstName: Faker.name.firstName(),
             lastName: Faker.name.lastName()
           }
       }
}
```

This takes care of naming the characters, but I’d like to know a bit more about them. Faker comes loaded with a commerce.color method that lets us generate random colors. Let’s use this give them hair and eye colors. 

Add the following to the lifecycle method: 

```js
eyeColor: Faker.commerce.color(),
hairColor: Faker.commerce.color(),
```

Finally, we’ll need to render these characters to the page. 

```js
   renderCharacters(character){
       return (
           <div>
               <p>{`${character.firstName} ${character.lastName}` }</p>
           </div>
       )
   }
[...]
render (){
	return(
		<div>
                    <h1>Generate Random characters!</h1>
                    {this.state.characters.map(character => 
                    this.renderCharacters(character))}
                </div>
	)
}
 
```
Finally, we're able to see characters on the page. 

 ![Characters with hair colors like lime green](https://dev-to-uploads.s3.amazonaws.com/i/76cg7p37gsvznvpo595y.png)

Those are some vibrant colors, but they’d probably only be appropriate if you’re writing about fantasy or anime. How can we create natural hair and eye colors?

## Creating Natural Colors

Faker doesn’t have a method for natural colors, but we don’t need one. After some cursory research, I found that [about 75% of the population has black hair](https://www.holleewoodhair.com/hair-color-statistics/#:~:text=What%20are%20the%20hair%20color,2%25%20has%20natural%20red%20hair.). We can build an object with these distributions. 

```js
const naturalHairColors = {
                40: 'black',
                75: 'brunette',
                95: 'blonde',
                99: 'red'
      }
```

To create a wider spread of different hair colors, I’ve set the black hair color to 40%, but you can pretty much set the color to whatever you want. 

To use this object, we’ll need to create a random number between 1 and 100. 

```js
let number =  Math.floor(Math.random() * 100) + 1
```
Then, we’ll look through the object to see which one of the keys is equal to or less than the number. 

```js
for (keys in naturalHairColors){
        if (number <= keys){
          return naturalHairColors[keys]
        }
      }
```
Creating an option for natural eye color follows a similar approach: 

```js
generateRandomNaturalEyeColor(){
 
       const naturalEyeColors = {
                60: 'brown',
                93: 'blue',
                95: 'hazel',
                97: 'amber',
                99: 'gray',
                100: 'violet red'
      }
   
      let number =  Math.floor(Math.random() * 100) + 1
      let keys;
      for (keys in naturalEyeColors){
        if (number <= keys){
          return naturalEyeColors[keys]
        }
      }
    }
```
These work great, but there’s no way for us to switch between using the built-in color() method and our new function. We’ll need to create a form to toggle between the two options. 


# Form to Toggle Colors

I chose to make the Faker library’s fantasy colors the default. With that in mind, I created a form to check which colors I wanted to be natural or fantasy. 


```js
<form onSubmit={this.handleSubmit}>
  <label>Use natural hair color
                       <input
                       name="naturalHColor"
                       type="checkbox"
                       checked={this.state.naturalHColor}
                       onChange={(e) => this.handleHairInputChange(e)} />
  </label>
[...]
</form>
```

For this controlled form, natural hair color will also need to added to the state. 

```js
naturalHColor: false
```

Toggling between the two will cause our state to change from false to “on” (or effectively true and false). Writing a handleHairInput function will take care of this state change.

```js
  handleHairInputChange(event) {
       if(!this.state.naturalHColor){
           this.setState({
               naturalHColor: event.target.value
           });
       } else {
           this.setState({
               naturalHColor: !event.target.value
           });
       }
     }
```

Finally, since this is a form, we’ll need a submit function. Submitting the form should also change all the characters, so we’ll need to reset our state as well. 

```js
reset() {
       this.setState({
           characters: []
       });
   }
```

The submit function is similar to the logic in our lifecycle method. We create five random characters and then populate the state with them. 

You’ll also need to check if the natural hair or eye color is set to on. To do this, check if the state for natural color is set to "on." If it is, use the generateRandomNaturalEyeColor() function. If not, use the Faker library.

```js
handleSubmit = (e) => {
       e.preventDefault()
       this.reset()
     
       for (let i = 0; i < 5; i++) {
           const character = {
             firstName: Faker.name.firstName(),
             lastName: Faker.name.lastName(),
             eyeColor: this.state.naturalEColor ? this.generateRandomNaturalEyeColor() : Faker.commerce.color(),
             hairColor: this.state.naturalHColor ? this.generateRandomNaturalHairColor() : Faker.commerce.color()
           }
        
 
           this.setState(prevState => ({
             characters: [...prevState.characters, character],
           }))
         }
   }
``` 
We now have a working character generator! 

![Gif that shows toggling between natural and Faker generated colors](https://dev-to-uploads.s3.amazonaws.com/i/9rfp0z2pnewkyf62emqs.gif)

Uh oh! Did you see my mistake here? Red hair color should actually be set to 100 instead of 99. 

```js
const naturalHairColors = {
                40: 'black',
                75: 'brunette',
                95: 'blonde',
                100: 'red'
      }
```

Fix it and you should be good to go!

# Conclusion 

We now have a random character generator that creates first names, last names, hair and eye color for our characters. We also have the option to switch between natural and fantastical colors.

By creating objects to hold random data, we can also create attributes such as age, alignment, motivations, etc. 

Faker.js also comes with an image library that can help us visualize how our characters act, dress, or feel. 

Experiment with the random data until you find a data set that works for you. Happy writing!