For my last project at Flatiron School, I created an app that allows users to search and add video games to a backlog and categorize games inside their backlog as not-started, started or completed. This post will describe the process I underwent to build my app.
Before I began coding I had a good idea of the components I would need to build for my app. I made one container component for each route and a couple basic components that I thought I would need. Next, I created a reducer and an 'addGames' action that fetches games from the RAWG API. I also connected each container component to the Redux store. After that I made a form component and wrote out the code necessary to get a list of games to show up on my home page after a user submits the form. Users could now search for games by title and would receive the first page of results from the API. Getting all the that done was straightforward since those were all things we practiced building in lessons.
Next, I started to style my home page using react-bootstrap. I made it so each video game was represented as a card. Confusingly, the cards were appearing very skinny and super tall. I didn't find out why this was but I solved it by making the card-container a flex-container and wrapping each card in a column component and giving those columns a specific width. This way the cards took up the full width of the columns and I could easily control the columns width using props passed to the 'col' component.
Although controlling the width turned out to be easy, getting the cards to all be the same height and look nice was a more complicated issue. Each card was a different height mainly because of differently sized images inside the cards. If I made each card take the full height of the column, there would occasionally be cards with lots of empty space which I thought looked ugly. There were a couple solutions I tried but the one I thought was the best was to give a maxHeight property to card-images to even out the size differences between cards. I also tried setting a max-height to cards but that wasn't a good solution because I did not have a good way of showing overflowed content. Moreover, a smaller but equally as difficult problem was making it so that the cards would not resize after clicking on them and changing their content. To solve this I used a React ref to save the column height and when a user clicks on the card I set the minHeight of the card to be the height of the column. This way, cards never shrink when a user clicks on them to flip them over.
The last thing I did with my home page was add infinite scrolling. Fortunately this turned out to be easy due to a nice package 'react-infinite-scroll-component' that I found from google.
After getting my home page to look pretty I added in my other routes, backlog and login, and their pages. One challenge that I faced while making my backlog page was handling moving a game from one category into another. Inside my backlog container's state are three lists representing the games in each category: started, not-started and completed. The issue was knowing which lists to update when a user moves a game to a different category. The way I handled this was to use variables for the keys that get updated inside my setState function. When a user selects a category they want to move a game to, a string gets passed to the handleSelect method, which is the same as one of the names of the keys inside the state of the backlog container. I use that string and the current status(completed, started or not started) of the game to determine which list to update. Because the string of game.status and the string that gets passed to handleSelect are the same as the names of the keys I was able to avoid using any comparisons inside my handleSelect method. This made my code clear and concise.
handleSelect = (newCat,game) =>{
const gameCategory = game.category
game.category = newCat
this.setState(prevState =>{
return{
[gameCategory]: prevState[gameCategory].filter(g => g.id!== game.id),
[newCat]: [...prevState[newCat], game]
}
})
}
The final step was to create a backend that sends and receives JSON Web Tokens. For this I followed the lesson from Flatiron that outlined this process. I didn't have much trouble making the backend itself but handling logins and making use of data from my API in the frontend turned out to be more challenging than I initially thought. However, it was nothing that I couldn't figure out on my own.
Using React to make a dynamic full-stack application was enjoyable and straightforward. I learned a lot about styling, JSON Web Tokens and working with data coming from multiple sources, for example, user-data coming from my backend and game-data from the RAWG API. Combining data to make unique and interesting apps is a common yet challenging task and I'm happy to have had this experience for myself. I feel good about what I achieved with this project.
Check it out: https://guarded-temple-25512.herokuapp.com
github: https://github.com/nrymarz/vg-backlog-tracker
Top comments (0)