Project 34 of 100 - React + Firebase Exercise Tracker v2 (Bonus: Filter text input with the npm bad-words package)
Tags: react, javascript, 100daysofcode, npm
Published: 2021-01-17 05:38:27

*Hey! I'm on a mission to make 100 React.js projects ending March 8th. Please follow my dev.to profile or my [twitter](https://www.twitter.com/jwhubert91) for updates and feel free to reach out if you have questions. Thanks for your support!*

Link to today's deployed app: [Link](https://100-react-projects-day-34-run-tracker-v2.netlify.app/)
Link to the repo: [github](https://github.com/jwhubert91/100daysofreact/tree/master/day-34-run-tracker-v2)

So, it's probably inviting malfeasance to claim my application is "bad word proof". It's easy to create bad words if you try, but I realized with past projects that if you create an application without authentication or validation and release it to the public you can get some unexpected results. To combat swear words from being entered easily into the text box of my exercise tracker I used the `bad-words` npm package.

##Summary of the Project
If you pay attention to my blog or Linkedin/Twitter posts you'll know that my last project was also an exercise tracker- with the same Firestore backend- but I think when pursuing a new skill it's often valuable to go back over previous skills to concrete the information. For that reason I wanted to re-do this project with a nicer Bootstrap-based front-end, like something you might actually use, and practice the backend code again.

The [previous version](https://dev.to/jwhubert91/project-33-of-100-simple-run-tracker-with-firebase-and-react-hooks-fb2) looked like this, and the difference, I think, shows:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t17pyox34d94kffk6q5u.png)

I go through the same process of creating a `firebase.js` file in the src directory of the application and initializing the connection to Firebase there, and export that configured connection to the rest of the app as a module with an `export` statement.

We then build a form component and use the React `useState` hook to collect input data from the user via the form. When the form is complete we send that data to the Firestore database, and file it under the `runs` collection with this simple line of chained Firebase methods:

```
import firebase from './firebase'

function handleSubmit(e) {
  ...
  firebase.firestore().collection('runs').add({run data goes here})
}
```

It was when we were defining the object to send to Firestore that I used the `bad-words` npm package's pre-built methods to filter out any unnecessary expletives. More on this later.

To view our exercises stored in the database, I created another component called `RunsList.js` with a simple Bootstrap table surrounded by a div. We use conditional rendering to show the sentence "There are currently no runs to display." if the database is empty or we get back no data. If there is data, we populate the table `tr` elements and build rows from the data with the Javascript `map` method to iterate through each object.

##`bad-words` npm package
There is a whole universe of cool npm packages out there and if you need something done in your application, chances are there is a package for it. I Google'd a question about filtering swear words and this came up. Its landing page boasts over 24,000 weekly downloads and implementing the package is extremely easy.

After installing the package just include it in your file and instantiate it like so:

```
var Filter = require('bad-words'),
    filter = new Filter();
 
console.log(filter.clean("Don't be an ash0le"));
```

I just used the native bad words library but they give you the option to define your own bad words as well, which is pretty handy. A package like this would be pretty simple to build with regex but it's nice someone put it out and maintains it.

So just a simple recap today but it was fun doing this again with better styling and a little bit of data manipulation for a better user experience. I'll be focusing on learning Firebase more over the coming weeks.