Select Page

I am working through Codecademy’s Ravenous React project. Here I want to break down the project so as to understand it.

The project is broken into three pieces.

Part 1

App Functionality

Screen has two search bars, one to search for restaurants, one to input where the restaurants should be located.
Above these search bars, user can choose from three filters: Best Match, Highest Rated, Most Reviewed.
Under the search bars is a button to submit the search.
Under that button appears a list of restaurants matching the search.
List items include a picture, an address, a title, number of stars, number of ratings, and the type of cuisine.

Where does the app get all the restaurant info? It uses the Yelp API.
It’s like we’re building a mini-Yelp with the Yelp API. It’s just for practice. 

App parts

The app has the following relevant components, all inside the src folder:
App.js, App.css, index.js and index.css files are inside the src folder (not in a subfolder).
The components folder in the src folder has three subfolders:
Business, BusinessList and SearchBar,
These folders contain the following files:
Business: Business.js & Business.css;
BusinessList: BusinessList.js & BusinessList.css;
SearchBar: SearchBar.js & .css & two picture files for the header, one for desktop and the other for mobile.

Functionality and connectedness of app parts

I am not sure what, if anything, index.js is doing in this app. So far (after having coded the first part of the app), it is not being used.

App

App.js imports BusinessList and SearchBar and renders the following code:

<h1>ravenous</h1>
<SearchBar/>
<BusinessList/>

SearchBar

So far (part 1 of the project) SearchBar.js doesn’t import anything.
It renders the search bars, the submit button and an unordered list of the searchByOptions: Best Match, Highest Rated, Most Reviewed.

Here is the code of renderSortByOptions (which is called in the render method)

renderSortByOptions () {
return Object.keys(sortByOptions).map( sortByOption=> {
let sortByOptionValue = sortByOptions[sortByOption];
return <li key={sortByOptionValue}>{sortByOption}</li>;
});
}

How does it work? Note that it uses the Object type, which is one of JavaScripts’ data types
 It is used to store various keyed collections and more complex entities.
Object()Turns the input into an object.
Object.keys()Returns an array containing the names of all of the given object’s own enumerable string properties.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object

So I guess Object.keys(sortByOptions)  takes the sortByOptions object

const sortByOptions = {
“Best Match”:”best_match”,
“Highest Match”:”rating”,
“Most Reviewed”:”review_count”

And returns an array of the names of all its enumerable string properties; these names are “Best Match”, … ; and the values named are “best_match” …

Then .map takes each of those names (“Best Match” … ), and for each one (called “sortByOption” in the code),  it creates a key called sortByOptionsValue by using the individual sortByOption as an index on the sortByOptions array.

Are the keys just numbers 0 … ? Otherwise, how can indexing be used to select a specific value?

But sortByOptions is not an array; it is an object.
The .keys turn it into an array to be mapped over, but does it change the sortByOptions variable from an object into an array, so that when the function uses sortByOptions[sortByOption], it is indexing an array? Or is sortByOptions still an object, and we are here indexing an object?

From googling around, it seems like indexing is only for arrays, so I guess somehow the sortByOptions object has become an array inside of this function, although I don’t think it is one outside of this function.

Anyway, the function then takes each sortByOptionValue and sortByOption pair and uses them to return a list item: return <li key={sortByOptionValue}>{sortByOption}</li>

I’m a little shaky on when you use “return”. They used it twice here. First we return the Object.keys(sortByOptions).map( sortByOption => …
And then within that  .map function (can we call it a function), we create the sortByOption and sortByOptionValues variables, assign them values, and then use them in the list item that we return. I guess functions have to return something and here we have nested functions?

Why are the hero pictures also included in the SearchBar folder and linked to by SearchBar? I guess because they are the backdrop of the search bars and the button and the filters — all the stuff SearchBar.js is rendering

BusinessList

BusinessList.js imports Business and renders like so:

render() {
return(
<div className=”BusinessList”>
<Business/>
<Business/>
<Business/>
<Business/>
<Business/>
<Business/>
</div>

As of part 1 of the project, BusinessList is rendering six businesses. I think we are going to change that so that it renders however many businesses the api returns for a given search, but for now it is rendering six businesses.

Business

So far Business.js starts with a variable called “business” that contains info about one business, like the name, # of stars, a link to a photo, etc.
Under that variable is class Business, which has nothing but a render with a return of information about a business. The information is created by accessing the “business” variable like so:

<p>{business.address}</p>

Render Chain

App.js renders the Ravenous title, the SearchBar and the BusinessList (a list of restaurants).

SearchBar.js renders the list of three SortBy options (Best Match, etc), the key-word search bar and the location search bar, and the submit button.

BusinessList.js renders a list of <Business />

Business.js renders information about and a picture related to a restaurant.

 

Part 2

App

App.js took the “business” object away from Business.js. It also added an array “businesses” that lists “business” six times.

BusinessList and SearchBar are child components of the App component. App.js still renders both < SearchBar /> and < BusinessList />, but now it has the template for each individual business, as well as an array of six “business” objects called “businesses” and now it passes the “businesses” array to its child elements like so < BusinessList business={businesses} />

 

SearchBar

This component was not changed in Part 2.

BusinessList

Instead of rendering < Business /> six times, now BusinessList.js renders the following code:
<div className=”BusinessList”>
{this.props.businesses.map( (business) =>
< Business business={business}/>
)};
</div> 

App now has the “business” object / template and an array “businesses” of “business” objects. App passes the businesses array to its children components, including BusinessList. BusinessList then accesses “businesses” via props and maps over that array to render an instance of the Business component for each business in the array. By adding the business property to each instance of the Business component, BusinessList sends all the info about each business to its child component (the Business component)

Business

App.js took the “business” object away from Business.js 
So now Business.js has to use props to access info about each business object.

You can do this either by changing each part in the code where you use the business object like so:

<h2>{this.props.business.name}</h2>

or you can add const { business } = this.props; to the top of the Business class and leaving the rest of the code unchanged like <h2>business.name</h2>

Render Chain

App.js renders SearchBar and BusinessList. The “business” object and an array “businesses” of the “business” objects now lives in App.js.
SearchBar.js renders the three SortBy options (ex: Best Match), both the general and the location search bar, and the submit button.
BusinessList gets a list of businesses from App.js via props and maps out each business from that list, and for each one it renders a <Business /> component with a business={business} attribute. That attribute passes all the information about a given business to the Business component.
Business renders information about each business, like the name and etc. It accesses this information via props. Again, the information was passed to it by it’s parent element BusinessList.