Returning to Liquor Cabinet: Fixing A Bug
Tags: react, fetching, bugs, devjournal
Published: 2021-07-25 20:33:33

So this last week I decided to deploy another old app of mine. If you read my post [Searching for Ways to Search: Two Methods Of Performing A Search With A Rails Back-End And A React-Redux Front-End](https://dev.to/maxjacobzander/searching-for-ways-to-search-two-methods-of-performing-a-search-with-a-rails-back-end-and-a-react-redux-front-end-45f0), you may recall my app "Liquor Cabinet". "Liquor Cabinet" is an app I built at the end of my time at Flatiron School with a React with Redux front-end and a Ruby on Rails back-end. I actually haven't altered all that much of it since then because I liked the idea of having something on my Github profile that can show the growth I've experienced since graduating. ("Liquor Cabinet" is built with a lot of class components, very few hooks, etc.)

Anyway, I decided to revisit the app this week to deploy it, so converted the database to Postgres and popped that up onto Heroku, updated the fetches on the front-end to reflect the new URL endpoint, and put that up onto Netlify (if you want to learn more about that process, you can read [this post here](https://dev.to/maxjacobzander/deploying-a-full-stack-app-for-the-first-time-vanilla-javascript-rails-api-2ocg)).

Fast-forward a couple of days and I'm talking to a couple of folks at a super cool company and one of them mentions to me that he is trying to use "Liquor Cabinet" but it isn't working. My first instinct was that it was actually a Heroku issue. "Liquor Cabinet" uses "free dynos" and, as I mentioned in my post about [deploying a full-stack app](https://dev.to/maxjacobzander/deploying-a-full-stack-app-for-the-first-time-vanilla-javascript-rails-api-2ocg), if the app uses "free dynos" and no server requests happen for 30 minutes, the server will stop running. If someone tries to make a request to the server, it will wake itself back up and start running again, but it does take a second. So I told him that he should wait a second and try again. Still no dice. I asked what he was searching for and tried it on my end and it seemed to work fine. But then I realized something. I was capitalizing my search. Could it be a case-sensitivity thing? How could I have missed that? I asked if he was searching with a capitalized first letter or not. He said that he wasn't and I asked him to try it capitalized. Bingo — it worked. I thanked him for exposing the bug and as soon as I got off the call, I hopped on VSCode to fix it.

My first thought was to go into the `drinks_controller.rb` file and look at the search method:
```
  def search
    @drinks = Drink.where("main_liquor LIKE ?", "%" + params[:q] + "%")
    render json: @drinks
  end
```

I thought that maybe if I tacked some methods on to `params[:q]` I may be on to something. I booted up my rails server...Not quite.

I took another moment to think about how the data was going back and forth between the front-end and the back-end. I looked at my `Search.js` and how I was handling the submission of the form. Turning to my `actions.js`, I looked at how my search fetch was happening:
```
export const searchDrinks = liquor => {

    return(dispatch) => {
        return fetch(`http://localhost:3001/api/v1/search?q=${liquor}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({liquor})
        })
        .then(resp => resp.json())
        .then(liquor => {
            console.log("liquor", liquor)
            dispatch({ type: "FIND_DRINK", payload: liquor })
        })
    }
}
```

Essentially, what we have going on here is that we are taking the input from the search bar and calling that `liquor`. We're then sending a POST request (used to send data, rather than say a GET request which is used to request data) to the back-end database, interpolating in the searched liquor to the end of the URL endpoint. Since data can only travel as a string, we're taking the JSON at the endpoint and turning it into a string and then, once it makes it back to the front-end, we're turning that string back into JSON and applying the reducer to update state. Cool.

Anyway, as I looked back on that, suddenly, the solution was obvious! Here's an example of what URL of a successful search on the back-end looks like: `http://localhost:3001/api/v1/search?q=Whiskey`. Can you spot what we're about to do?

The solution laid in altering what's being interpolated into the fetch request. Since what we're interpolating is exactly what the user is searching for, we just have to alter it to fit the format of the database (in this case, capitalizing the first letter). So how do we do that?

So let's say our searched `liquor` is whiskey. Since our searched term is a string, we need to use string methods. If we were to call `.toUpperCase()` on `liquor`, we would get `WHISKEY`. Since we only need the first letter capitalized, we need to separate out that letter. We can use `.charAt()` to return out just the character we need and chain on `toUpperCase()` to that character. If we then call the string method `.slice()` on `liquor` and only provide a starting index, we can return the rest of the letters as a new string. Concatenating those two returned values, we can get the whole word with just the first letter capitalized:
```
liquor.charAt(0).toUpperCase() + liquor.slice(1)
```

Popping that into the fetch looks like this:
```
 return fetch(`http://localhost:3001/api/v1/search?q=${liquor.charAt(0).toUpperCase() + liquor.slice(1)}`
```
And that worked! Cool. But then I was thinking about other ways that this solution could be broken and realized that, while I was successfully capitalizing the first letter on the entered search term, I wasn't accounting for someone searching with caps lock on or someone else searching with rAndOMizeD cApITal LetTeRS. Testing that out in the app, my suspicions were confirmed.

Having just fixed the first issue, this was a *super* simple fix. I went back into `actions.js` and called `.toLowerCase()` on the sliced out characters. This will take whatever the user inputs and make it lowercased, also fitting the necessary search format.

All together, the fetch now looked like this:
```
 return fetch(`http://localhost:3001/api/v1/search?q=${liquor.charAt(0).toUpperCase() + liquor.slice(1).toLowerCase()}`
```
and *that* both worked *and* accounted for any weird capitalization. Testing it out in the app, we were looking good and successful!

I'm super glad I had this experience and it just goes to show how important it is to have other eyes on your work! If you would like to check out this app, you can do so [here](https://liquor-cabinet.netlify.app/)!