Making a Community-Centered Yelp! 
Tags: codenewbie, flatironschool, react
Published: 2021-02-05 22:15:21

For my final project at the Flatiron School, I wanted to create a yelp-like app that would celebrate small businesses and the rich diversity of local shops in Los Angeles. My yelp-clone would allow a user to filter the businesses searched for by the communities one wanted to support so a person could search through BIPOC-owned businesses, LGBTQ+-owned businesses, Women/Womxn-owned businesses, and/or businesses that have a documented track record of having a social impact commitment. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gitqr93kjw4k9vkjt0wa.png)

This project presented me with a number of logistical challenges, some of which I'm still working through (if anyone reads this and can help me figure out why my google map markers won't render, holler!). To make this application, I used a React-Redux frontend with a Rails API backend. The API is a database that I constructed myself. It, unfortunately, does not contain every minority-owned or social-impact-committed business in LA because I'm only one woman and that is A TON of data, BUT I designed this application to also be open-sourced, thus any individual could foreseeably add a missing business or shop to the backend database. 

The first and main challenge in my project was to replicate the basic feature of yelp: creating a search bar that directs you to a list of relevant businesses. 

If you're familiar with react, you're likely familiar with React-Router, which is a package that allows you to make a SPA, or single-page application, into a site with dynamic urls and navigational components. My landing page is just one big search bar and I wanted to have the search button take the user to a url that would read something like `localhost:3000/categories/:id/shops` where the shops displayed were filtered by the tags the user selected in their search. My first major challenge was figuring out how to hook up a button to link to a page whose url parameters would be determined by a user. 

First thing's first, to conquer this challenge I knew I would need that route to exist and to point to the component that would display a particular category and all of its shops. In my App.js, I set up my `Router`, which comes--originally titled Browser Router--from React-Router, with a `Route`--another navigational component that you get from React-Router that pointed to that exact url path. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eilu0ot0o1vjvqf96m9b.png)

You'll notice to that I have a '/' path Route (my 'home' page route) set to render my `HomeSearch` component which receives (props). Render is a function that allows you to pass props to a component on render. These 'routerProps' include things like `history`, `match`, and `params`. We'll get back to that later.
In my `HomeSearch` component, I set up a local state that includes a key, 'search' whose value was determined by what a user types in the input field.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7i8no3pil3x7533dfoo2.png)

I have a simple `handleChange()` function which handles the setting of state to the user's input: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/imzc19mksftr0ow309xm.png)

Once a user types a business category such as 'restaurants' and hits submit, I had to create a function that would match whatever they had typed to one of the 15 or so categories I had programmed into my database. I sliced the first three characters from their search term and filtered through my list of categories (which I had retrieved by connecting this component to global state and pulling all of my categories into props) to match the first three letters of one of my pre-programmed categories to their search term. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rodcocsk5qha56tqczln.png)

So that gave me the `matchedCategory` which in turn would give me that category's id, which I would eventually insert into the url I was directing the user to. If there was no category that matched a user's search term, I programmed an alert to pop-up gently redirecting the user to type something else in the input field. 

Once a successful match occurred, I knew I would not only want to direct the user to that category's 'show' page but also I want the page to display a list of shops belonging to that category that are filtered by the tags the user selected in their search. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ect0smf644jt7o0ru57h.png)

I filter through the tags in state to see which ones are checked and use that information to create my query string! Query strings are commonly used for embedding parameters into a URL. Query strings usually begin with a `?q=` and multiple parameters are separated by a `&`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/d0c62nb8stcl0s5nn65g.png)

Here, I'm going through the selectedTags and spliting their names on the spaces, and then rejoining them with an underscore in between. I create my `queryString` by joining the tags (if there are two or more--if there is only one it won't have any other manipulation) with a `&`. I insert that query string, along with my `matchedCategory` into my future url string (the url I want to direct the user to) and `push` it into the current component's history (remember, when you render a route, the component rendered receives props that include `history` which keeps track of url paths that have been visited). When that happens, the user gets pushed over to the next page! So, at the end of the day, my search function looks like: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ae5hrtlgsdeya7x6c8dq.png)

Once the user arrives at that next page, they have the category and thus all of its shops available to them. I used the parameters included in the url to filter the shops by their tags and then display them on the page, thus mimicking the key 'search' feature of yelp for my React project!