Grey’s Anatomy Lorem Ipsum Generator Tutorial
Tags: netlify, tutorial, javascript, react
Published: 2019-06-02 17:13:25

---
title: Grey’s Anatomy Lorem Ipsum Generator Tutorial
published: true
description: This tutorial is going to walk through how to create a Grey’s Anatomy or other-themed Lorem Ipsum generator with React and Netlify Functions
tags: netlify, tutorial, javascript, react
canonical_url: https://www.aboutmonica.com/blog/greys-anatomy-lorem-ipsum-generator
cover_image: https://thepracticaldev.s3.amazonaws.com/i/s7bc4koh3x0h0qxblloq.png
---

This tutorial is going to walk through how to create a Grey’s Anatomy or other-themed Lorem Ipsum generator. I’m a huge fan of the show, Grey’s Anatomy (and Shonda Rhimes in general) for a while so I was overdue for creating a Grey’s Anatomy-themed Lorem Ipsum generator. Lorem Ipsum is generated, nonsense text that is used in design and publishing as placeholder text. Traditionally, Lorem Ipsum is written with Latin words but there are variations that involve non-Latin words as well.

![This tweet thread about being a Shonda Rhimes enthusiast https://twitter.com/waterproofheart/status/408430997517393920](https://thepracticaldev.s3.amazonaws.com/i/ekb8qf4uciz0tsk8967y.png)


The live version of the Grey's Anatomy Lorem Ipsum Generator website can be viewed [here](https://greysanatomyloremipsum.netlify.com/) and the code for this tutorial can be viewed
[on Github](https://github.com/M0nica/greys-anatomy-lorem-ipsum-generator/tree/loremIpsumTutorial).

Here’s an example of the type of text that is generated by the Grey's Anatomy Lorem Ipsum generator:

“real hospital Dr. Cristina Yang well a trauma surgical fellow badly chief of pediatric surgery George Ellis orthopedic surgeon Dr. Shane Ross approximately Dr. Callie Torres exactly Dr. Izzie Stevens Izzie chief of plastic surgery an anesthesiologist Meredith’s father Zola Seattle Erica certainly Meredith Dr. Shane Ross basically basically Tucker maybe Dr. Virginia Dixon whoever Chief Richard Sadie significantly nicely Arizona real very Dr. Colin Marlowe Zola mostly things Dr. Teddy Altman rather Arizona Dr. Teddy Altman Seattle Dr. Izzie Stevens my person”

The above paragraph makes absolutely no sense but if you’re familiar with Grey’s Anatomy there are some familiar terms baked in there.

## Requirements

To get the most out of this tutorial you should:

- Have familiarity with git and JavaScript
- Have a GitHub or GitLab account (in order to use Netlify functions).

## Table of Contents

- [Set Up](#set-up)
- [Verify Set Up](#verify-set-up)
- [Calling the Netlify function from React](#calling-the-netlify-function-from-react)
- [Adding Lorem Ipsum Logic](#adding-lorem-ipsum-logic)
- [Methodology](#methodology)
- [Formatting Response](#formatting-response)
- [Deploy](#deploy)

## Set Up

In order to jump-start this project, I used Netlify’s [GitHub - netlify/create-react-app-lambda](https://github.com/netlify/create-react-app-lambda) starter. Netlify is a hosting service that specializes in hosting JAMstack websites, as of writing this tutorial, has a pretty comprehensive free tier that integrates well with deploying GitHub projects to the world wide web. JAMstack is used to describe static websites that are compromised of JavaScript, APIs, and Markup. You can learn more about what is or isn’t considered JAMstack here [JAMstack | JavaScript, APIs, and Markup](https://jamstack.org) ,

The `create-react-app-lambda` repository integrates Netlify’s functions with `create-react-app` which means out of the box you can deploy a React application that calls, Serverless functions, which you may know as Amazon Web Services (AWS) Lambdas. These functions can make asynchronous calls and process data but they must be stateless, meaning that given the same inputs the output will be the same. With Netlify you can deploy and manage AWS Lambda’s technology without an AWS account. You can read more about Serverless Lambda Functions on Netlify here: [Functions | Netlify](https://www.netlify.com/docs/functions/).

Let’s get started by copying over `create-react-app-lambda` . Click on the “Deploy to Netlify” button in the README.
![picture of green deploy to netlify button](https://thepracticaldev.s3.amazonaws.com/i/ik1ue07vhfbcsqy0hldl.png)


This one-click button allows us to set up React + Netlify Functions without having to do heavy lifting. Essentially when you click the button you are creating a new site in Netlify and a connected GitHub repository. It takes a few minutes for the GitHub repository to populate with the files but once it is done populating you should be able to visit Netlify and view your site. If you’d like a better understanding of why things were set up the way they were in the `create-react-lambda-app` then check out [this video](https://www.youtube.com/watch?v=3ldSM98nCHI) by Shawn Wang (swyx) for more context.

After clicking the "Deploy to Netlify" button you should see something like this:
![welcome to netlify screenshot](https://thepracticaldev.s3.amazonaws.com/i/gqtabyzvj8rdm4kqudg5.png)


Note: Comprehensive instructions for interacting with the `create-react-lambda-app` project live in the README. I will highlight the most important pieces to interact with the app but encourage exploring the README for more information and to further enhance the application.

So once the repository that you created in Netlify is populated with files from `create-react-app-lambda` you should `git clone` the repo. The repository that you are cloning should be named after the repo that you created, i.e., `git clone git@github.com:your_username/app-just-created`. You may have to refresh the repository page before the files are populated.
![git clone screenshot](https://thepracticaldev.s3.amazonaws.com/i/9otr85x4yqqbtkgqgjnb.png)

Once the project is set up you should `cd` into the project directory and run `yarn` to install all of the dependencies. You can run `yarn test` to ensure that all of the tests are passing and the project was set up properly.

The Netlify functions should be created in `src/lambda`. If you look in that folder there are two sample functions `async-dadjoke.js` and `hello.js`. For our use case we don’t need an `async` function so let’s look at the `hello.js example`

In `hello.js` we are getting the `queryStringParameters` from the event in order to log them. `queryStringParameters` can be accessed from the event like `event.queryStringParameters` or by destructuring the event object like `const {queryStringParameters} = event`.

```javascript
export function handler(event, context, callback) {

  console.log(“queryStringParameters”, event.queryStringParameters)

  callback(null, {

    statusCode: 200,

    body: JSON.stringify({ msg: “Hello, World!” })

  })

}
```

Every Lambda function has a handler function. This handler function can take event, context, and callback. The event is based on what the endpoint received when the request was made it can include things like cookie information, headers, queryStringParameters, etc. The context object provides additional insight regarding a Lambda’s execution. You can learn more in the AWS docs here:
[AWS Lambda Function Handler in Node.js - AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html)

## Verify Set Up

In order to tests the functionality of the endpoint we should run `yarn start:lambda`, in the directory we just clone, which will run all of your Lambda functions. And then you can visit `http://localhost:9000/hello` or `/` whatever the name of your function is. On this page, you should see: `{“msg”:”Hello, World!”}` since that is the body of the endpoint’s response.

## Calling the Netlify function from React

Next, I would recommend customizing the naming conventions in the project to better fit your needs. I renamed `hello` to `generate-lorem-ipsum`, so first I rename the`hello.js` file to `generate-lorem-ipsum` and then in the `LambdaDemo` component in `app.js` , I replaced the call to `hello` on button click to `generate-lorem-ipsum` . While I was there I also deleted the button related to `async-dadjoke` and removed the associated file. So I went from

```jsx
<button onClick={this.handleClick("hello")}>{loading ? "Loading..." : "Call Lambda"}
</button>

<button onClick={this.handleClick("async-dadjoke")}>{loading ? "Loading..." : "Call Async Lambda"}
</button>
```

to:

```jsx
<button onClick={this.handleClick("generate-lorem-ipsum")} className=“button”>
            {loading ? “Loading…” : “Generate Lorem Ipsum”}
</button>
```

The button is calling the Netlify function on click, you can look at the `handleClick for more information` about what happens when you click on the button, initially It returns loading as the state and then eventually the response.msg.

Note: I updated references to `LambdaDemo()` to `LambdaCall()`in `App.js` because it’s show time!

In order to check the lambda is still being called and returning a response you should run `yarn start` (while `yarn start:lambda` is running in another terminal window). You should be able to visit http://localhost:3000 and see the React app with a “Generate Lorem Ipsum” button. If you click then the words “hello world” should appear on the site below the button.

## Adding Lorem Ipsum Logic

So now we need to edit the `generate-lorem-ipsum.js` file so that it returns Lorem Ipsum and not “Hello World”. We will achieve this by creating a word bank of terms in `words.js` and the following functions in the `generate-lorem-ipsum.js` file:
`handler()`
`generateLoremIpsum()`
`generateWords()`
`generateParagraphs()`
`getRandomInt()`

The `handler()` is the entry point into the file, therefore any functions that need to execute should either be called in the `handler()` or called by the functions that the `handler()` calls. First, we destructure the event to get the `queryStringParameters`.

For example, if someone calls our endpoint with the following query string parameter
`/generate-lorem-ipsum?paragraphs=4&words=0`

Then we would de-structure the event object to determine that the endpoint was requested to return 4 paragraphs and 0 words.

``` javascript
const event = {
queryStringParameters: {
paragraphs: “4”,
words: “0”
}
};
```

The handler will call a function `generateLoremIpsum` to actually handle generating the text, it takes in whether or not multiple paragraphs or just words should be returned. By default if there are no `queryStringParameters` it will return 4 generated paragraphs.

The `handler()` could end up looking something like this:

``` javascript
export function handler(event, context, callback) {
  const { queryStringParameters } = event;
  const { paragraphs = 0, words = 0 } = queryStringParameters;

  let isParagraph = Boolean(paragraphs);
  let count;

  if (paragraphs > 1) {
    count = paragraphs;
  } else if (words > 0) {
    count = words;
  } else {
    isParagraph = true;
    count = 4;
  }

  let response;
  try {
    response = isParagraph
      ? generateLoremIpsum(isParagraph, count).join(" ")
      : generateLoremIpsum(isParagraph, count);
  } catch (error) {
    console.log(error);
  }

  callback(null, {
    statusCode: 200,
    body: JSON.stringify({ msg: response })
  });
}
```

In this example `generateLoremIpsum()` is a function called by the `handler()` and used as a fork in the road to determine if multiple paragraphs should be generated or just one based on if `isParagraph` is true or false.

``` javascript
export function generateLoremIpsum(isParagraph, count) {
  if (isParagraph) {
    console.log(`Trying to construct ${count} paragraphs`);
    return generateParagraphs(count);
  } else {
    console.log(`Trying to return ${count} words`);
    return generateWords(count);
  }
}
```

If we are generating a single paragraph the `generateWords()` will be called directly. This function creates an array of random words (based on getting a randomInt and adding the word at that index to the array until we reach the desired `wordCount`. In order to format the words once we have all of the words the words are formatted like `const formattedWords = <p>${words.join(" ")}</p>` in order to easily be able to transform the function’s response into an HTML paragraph later.
 
```javascript
export function generateWords(wordCount) {
  let words = [];
  console.log(wordCount);

  for (var i = 0; i < wordCount; i++) {
    words.push(WORDS[getRandomInt()]);
  }
  const formattedWords = `<p>${words.join(" ")}</p>`;

  return formattedWords;
}
```


The random int in the `generateWords()` function is calculated with the following function:

``` javascript
export function getRandomInt() {
  return Math.floor(Math.random() * Math.floor(WORDS.length));
}
```

In the case where we are generating paragraphs we need the function `generateParagraphs()`. This function will generate X paragraphs with 50 words until it reaches the paragraphCount. It does this by calling the `generateWords()` function X times where X equals the `paragraphCount` that was passed in.

``` javascript
export function generateParagraphs(paragraphCount) {
  let paragraphs = [];
  for (var I = 0; I < paragraphCount; I++) {
    paragraphs.push(generateWords(50));
  }
  return paragraphs;
}
```

In order for any of the above to work we need a word bank to draw from. At the top of `generate-lorem-ipsum.js` we should `import { WORDS } from "./words";` and then in the same directory create a file called `words.js`. In `words.js` we are going to create an array called `WORDS` and export it so that other functions can read it.

I created an array with just filler words( `fillerWords`) and another with Grey’s Anatomy and medical terms (`greysAnatomyWords`).
Used ES6 spread operator to combine the arrays into one. `export const WORDS = […greysAntomyWords, …fillerWords];`

The full file should look something like:


``` javascript
const greysAnatomyWords = ["Meredith Grey", "Shonda Rhimes", "Epi", "Cardio"];

const fillerWords = [
  "actual",
  "actually",
  "amazing"
];

export const WORDS = […greysAntomyWords, …fillerWords];
```

## Methodology

In a full blown project we would need a lot of words or else it will be too repetitive. If you want to create another type of themed Lorem Ipsum then you would replace the `greysAnatomyWords` with words from a theme of your choice.

For the grey’s anatomy words I brainstormed and also found some lists like this [Grey’s Anatomy Baby Names article](https://www.sheknows.com/parenting/articles/1008783/greys-anatomy-baby-names/) that I was able to re-purpose. The process of cleaning up the data and formatting into valid JSON can be a bit tedious, I did find and replace for formatting where I could and some manually updating as needed. This allowed me to get as much data as possible with minimal effort (I.e., automating the scraping of terms). I ended up with about 140 terms for my generator but if I needed a larger data set then it may have made sense to consider exploring a tool like BeautifulSoup or Selenium to automate scraping a data source and saving that data into a valid JS file.

Note: Depending on how repetitive data is can create Map or filter to make sure that the array of words only has unique values.

I decided to add in filler words so that the generated Lorem Ipsum text would have a healthy mix of verbs and adverbs in addition to the themed. I Google’d filler text and found a repository where I copied the “filler words” from [fillers_data.txt](https://github.com/words/fillers/blob/master/data.txt).

Now if you run `yarn start:lambda` and visit `http://localhost:9000/generate-lorem-ipsum/`you should see 4 generated paragraphs of lorem ipsum returned. It should look something like:

```
“msg”:”<p>especially surgicial mostly try hospital anyway Seattle Dr. Lucy Fields Alex a trauma surgical fellow Dr. Mark Sloan my person heavily wherever Theodora Duquette Dr. Virginia Dixon cried a nurse a neurosurgeon really Margaret Dr. Mark Sloan Dr. April Kepner Meredithâ€™s father literally Dr. Alex Karev Dr. Izzie Stevens an anesthesiologist Denny much necessarily Surgery a trauma surgical fellow surely hardly Owen rather Shepherd totally cried chief of pediatric surgery Theodora Dr. Robert Stark Olivia an anesthesiologist get her up to CT actually Cristina Dr. Finn Dandridge</p> <p>Tucker Virginia Callie Torres mostly hardly Maggie Maggie get her up to CT hardly get him up to CT quite stuff Dr. Mark Sloan whenever Dr. Richard Webber try George amazing Dr. Sydney Heron Dr. Jackson Avery actual quite nicely Richard stuff might Dr. Owen Hunt get her up to CT orthopedics Yang obviously mostly intubate her wherever orthopedic surgeon typically Margaret Karev effectively Alex Dr. Mark Sloan Seattle Dr. Alex Karev push one of epi try practically Dr. Alex Karev intubate him so</p> <p>start significantly start fairly get him up to CT slightly Dr. Alex Karev chief of plastic surgery slightly Dr. Robert Stark Meredithâ€™s mother Norman actually completely Izzie Dr. Mark Sloan particularly Alex basically Adele clearly like usually Seattle Dr. Alex Karev typically chief of plastic surgery get him up to CT essentially ultimately my person exactly Norman specifically Virginia effectively O’Malley intubate her Virginia Tucker my person a surgery resident largely most a veterinarian basically she’s in V-Fib try simply Seattle</p> <p>heavily Dr. Callie Torres essentially Dr. Jackson Avery whoever a nurse Dr. Mark Sloan definitely my person Olivia Harper Dr. Alex Karev essentially approximately generally my person exactly Dr. Miranda Bailey Dr. Preston Burke right a plastic surgeon Norman Theodora basically a cardiac surgeon chief of plastic surgery chief of plastic surgery essentially Dr. Jackson Avery Tyler Christian much seriously Meredithâ€™s mother slightly easily Mark my person maybe Mercy West Alex Erica Derek certainly badly rather hospital Denny Dr. Norman Shales Dr. Lexie Grey significantly Dr. Jackson Avery</p>”
```

## Formatting Response

This blob of text is not formatted yet but we will worry about that in the React app. So let’s switch back to `app.js` . We are already printing the messages if you run `yarn start` and go to `localhost:3000` you will see the same body text we just saw. Let’s use a library to format the response as actual HTML.

We will use the “html-react-parser” package. It can be installed by running `yarn add html-react-parser` and then add this `import parse from “html-react-parser”;` to the top of your `app.js` file in order to import it. Instead of just returning the `msg` in `LambdaCall` let’s replace `msg` with `{msg && parse(msg)}`. This says to parse the HTML of the `msg` and return it whenever there is a `msg`.

This part of the tutorial is choose-your-own-adventure. After setting up the Lorem Ipsum text generation logic. I went on to prettify the site to make it look more customized than the standard `create-react-app` boilerplate. One of the tools I used was this [fancy button generator](http://buttonoptimizer.com/). I recommend playing around with the CSS until it matches the aesthetic that you want.

### Deploy

Thanks to Netlify’s continuous deployment, if you clicked the “Deploy to Netlify” button on the first step then your website will be deployed to Netlify once you merge your changes into the master branch of your project’s repository. Also, if you open a pull request Netlify will generate a preview. This should mirror what you see when running the site locally.

The final code can be viewed on the `loremIpsumTutorial` branch of the [greys-anatomy-lorem-ipsum-generator](https://github.com/M0nica/greys-anatomy-lorem-ipsum-generator/tree/loremIpsumTutorial) repository.

Please share with me on Twitter, [@waterproofheart](https://www.twitter.com/waterproofheart) if you end up creating a Lorem Ipsum generator or another app with the Netlify functions after reading through this tutorial.