DEV Community

Terry Threatt
Terry Threatt

Posted on • Edited on

Final Bootcamp Project

Final project

I wrapped up my final project for the Flatiron School Bootcamp. I highly recommend this bootcamp if you have some knowledge gaps like I did and you are looking to get your first job as a developer.

For my final project, I was built a laptop rental web application for remote teams. In the project, I was tasked to build out a Ruby on Rails API and a React frontend that featured Redux for state management as well as React-Router for client-side routing.

Success

A big success for me was working on the backend. I am learning towards working on the backend more in the future. This is my second Rails API I have created. So it was really great to build out these parts:

# routes.rb
Rails.application.routes.draw do
  resources :rentals
  resources :laptops
end

#laptop.rb 
class Laptop < ApplicationRecord
    has_many :rentals
    validates :name, :specs, presence: true
end

# laptops_controller.rb
class LaptopsController < ApplicationController
  before_action :set_laptop, only: [:show, :update, :destroy]

  def index
    @laptops = Laptop.all

    render json: @laptops
  end

  def show
    render json: @laptop
  end

  def create
    @laptop = Laptop.new(laptop_params)

    if @laptop.save
      render json: @laptop, status: :created, location: @laptop
    else
      render json: @laptop.errors, status: :unprocessable_entity
    end
  end

  def update
    if @laptop.update(laptop_params)
      render json: @laptop
    else
      render json: @laptop.errors, status: :unprocessable_entity
    end
  end

  def destroy
    @laptop.destroy
  end

  private
    def set_laptop
      @laptop = Laptop.find(params[:id])
    end

    def laptop_params
     params.require(:laptop).permit(:name, :specs)
    end
end
Enter fullscreen mode Exit fullscreen mode

Challenge

My biggest challenge was learning about the predictable state container Redux and implementing it in the application. I discovered it very scalable to have a centralized store for your state that you can utilize in many components.

Here: The handleSubmit event handler triggers a Redux dispatch action to handle for the Redux action creator.

# LaptopInput.js
class LaptopInput extends Component {
    state = {
        name: '',
        specs: ''
    }

    handleChange = e => {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit = e => {
        e.preventDefault()
        this.props.addLaptop(this.state) // Dispatch 
        this.setState({
            name: '',
            specs: ''
        })
    }

    render() {
        return (
            <div>
                <br/>
                <h1>Add Laptop</h1>
                <br/>
                <form onSubmit={this.handleSubmit}>
                    <label>Name:</label>
                    <input type="text" placeholder="Name" value={this.state.name} name="name" onChange={this.handleChange}/>
                    <br/>
                    <label>Specs:</label>
                    <textarea placeholder="Specs" value={this.state.specs} name="specs" onChange={this.handleChange}/>
                    <br/>
                    <input type="submit" />
                </form>
            </div>
        )
    }
}

export default connect(null, { addLaptop })(LaptopInput) // Connects to Redux and maps a dispatch action to state
Enter fullscreen mode Exit fullscreen mode

Here: we receive input from event handler to request a new laptop be created and the API response to be dispatched the Redux store.

# laptopActions.js
export const addLaptop = (laptopInput) => {
    return (dispatch) => {
      return fetch('http://localhost:3000/laptops', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json'
            },
            body: JSON.stringify(laptopInput)
            }
        )
        .then(res => res.json())
        .then(response => {
            console.log(response)
            dispatch({ type: 'ADD_LAPTOP', laptop: response.laptop })
        })
    }
}
Enter fullscreen mode Exit fullscreen mode

Here: We hit our Redux reducer and add the new laptop into the state to be used all over the application with the 'ADD_LAPTOP' action type.

# laptopReducer.js
export default function laptopReducer(state = {laptops: [], laptop: {}, loading: false}, action) {
    switch(action.type){
        case 'GETTING_LAPTOPS':
            return {...state, laptops: [...state.laptops], loading: true}
        case 'GET_LAPTOPS':
            return {...state, laptops: action.laptops, loading: false}
        case 'ADD_LAPTOP':
            return {...state, laptops: [...state.laptops, action.laptop], laptop: {...action.laptop}}
        default:
        return state
    }
}
Enter fullscreen mode Exit fullscreen mode

Farewell

So now you a great deal about my final React-Rails bootcamp project. If you enjoyed this post feel free to leave a comment about your experience with React, Rails, or your bootcamp experience.

Happy Coding,
Terry Threatt

Top comments (0)