DEV Community

Chris Baum
Chris Baum

Posted on

Flatiron Phase 5 Portfolio Project - BetterDad

For my final Flatiron portfolio project I have created a web application called BetterDad.

Being a dad is extremely rewarding and I absolutely love my kids. However, it can come with challenges. The job of being a dad never ends, at many times it can be frustrating or even scary. Balancing work life, home life, and personal time can be difficult. These challenges can lead to times of sadness and even depression. BetterDad was created to help combat these feelings. It was inspired by a TED talk that I watched several years ago by Jane McGonigal. She was able to fight depression through incorporating aspects of a game into her life, making her life more goal oriented and provides motivation to continue to move forward through emotionally tough times.

The main requirements of the project were to have a React front-end that utilizes Redux for state management. The back-end would be a Ruby on Rails API that would handle data manipulation that would then be fed to the front-end.

I started with the back-end Rails application and the sign-up/login of the users from the front-end React application. Bcrypt was used to encrypt the password and authenticate. I also wanted to provide a way for the application to recognize a returning authorized browser client so that the user does not have to login every time they go the the url. This was done by having the backend assign an encrypted JWT token and saving it to the local storage of the browser client. Then whenever a request was made from the front-end to the back-end the token would be sent in the Authorization:Bearer header of the POST request. This was the first time setting this up, so it took a little bit of research and time to get it right.

In the Rails application, I also wanted several items to be updated on a daily basis automatically for the user: eight daily tasks were to be assigned and a daily quote that would be viewed by all users. This involved creating some code that could look at the created_at or updated_at time and comparing to current day time and re-assigning the tasks and quote.

When building the front-end I wanted to limit the number of routes that were being used to make the user interface feel more centralized to their profile. The minimum requirement was 3 routes, which I stuck to. The welcome page that is the base URL was one route. The welcome page had a button to the About page. This is extra information that a user wouldn't view often and are not a part of their specific user profile so I did break that out into its own page/route. Once logged in you are taken to the profile page which is the third route. I wanted to utilize the framework as much as possible to so I did research into React-Bootstrap components that were available. I found the Offcanvas component to be very useful to being able to add functionality and different information to a page without changing the route. This made the experience feel more seamless. I added the Signup form, history of completed tasks, favorited tasks, and user settings as offcanvas components that extend out from the side when the navigation button is clicked.

Image description

Using the react-bootstrap components was nice but I did run into some challenges with it. It can be a little unwieldy when you want to customize certain bootstrap components. I wanted my styling to stay with a particular color pallet, which was not standard to the bootstrap buttons. I researched how to do custom coloring for the buttons. However when I would initially put in new css styling, I would see the button change to what I wanted but when the page would re-render the styling would revert back. Looking into this issue, I found that others had this issue. The consensus for the easiest route to resolve the issue seemed to be to use inline styling with the buttons as bootstrap tends to default to that. Obviously this is not preferred because each Button component has to have the styling cut and pasted into it. For a much larger application it would probably be worth doing some more research to figure out if there is a way to use a CSS file to style a custom variant and then each button can just use the same variant to style it. For sake of time and since it is a smaller application I left it with inline styling as it isn't "wrong", but recognize it is likely not the preferred method in a larger application.

Since the Flatiron curriculum was developed several years ago I did do some research on the modern React framework and current preferences/standards. I found that class components, though still around and supported, are typically not what is preferred for new React applications. The push from React devs and the community is to use Hooks. Hooks are a functional component that can be utilized in a similar way to class components but have advantages:

  • Hooks are more lightweight. Below is an example of a Hook (left) versus a Class component (right):
    Image description

  • Allows you to implement state in a much more elegant/simplified way.

  • Better separation of concerns.

  • Code to connect to Redux store and dispatch is more intuitive and simplified.

    const currentState = useSelector((state) => state)
    const dispatch = useDispatch()
Enter fullscreen mode Exit fullscreen mode
  • Hooks utilize "return" rather than "render". This allows hooks to return values rather than only render a div, increasing the flexibility and usability of the Hooks if needed in your application.
  • There are many more advantages as well which you can find by googling "Hooks vs Class Components" if you wish to do more research.

Due to the many advantages, I did utilize Hooks rather than Class components in this application and believe strongly in them as they are quite a bit simpler and intuitive to use. React Class components feel very specific to React and are not very intuitive to connecting to a Redux store or dispatching. The Hook components feel more like a standard function/method that is used in javascript and ruby (again I would refer to the pictures above in the bullet points to show the Hook versus the Class component).

One more challenge that I ran into was implementing the use of Thunk, which was a requirement to utilize some asynchronous fetching. When I would update a user setting I have a message that is displayed to indicate if it was successful or not. When I implemented the async fetch using Thunk, I would render my component before the fetch was completed, so my redux state would not get updated in time to display my message. This took some time to resolve. The solution, since I was using Hooks, was to utilize UseEffect which allows you to perform side effects in functional components. In simple terms, we are telling React that the component needs to do something after the render. In my case I run the userSettingsMessage function after the render which forces the state to be set again and message to render properly.

useEffect(() => {userSettingsMessage(currentState.usersReducer.user[0].message)})
Enter fullscreen mode Exit fullscreen mode

I very much enjoyed developing this project and proving that I am capable of handling the front-end as well as back-end development of a web application from start to finish! I'm also proud that I did the research utilizing Hooks and react-bootstrap as these were not covered in the standard classwork, which is more simulated like how a real software engineering job would be. A class is not going to be handed to me for everything and I am going to have to find the resources and figure it out myself.

I can see why a team of full-time developers is needed at web application companies. Through the process I continuously was finding different ways to do things and refactoring and can see how a version 1 of a project would be pushed out, functional, but not optimized or perfect. Then optimized and fixed over a significant amount of time. It felt like I could spend hours and hours refactoring and finding better ways to do things. At some point is time to say it is "good-enough" and push it to the world!

Top comments (0)