Setting state when page loads, Depending on (database?) contents

Viewed 29

So in my code, I want it where a single User can only have one booking/reservation per Hotel, but every time after the page is refreshed, my state keeps reverting back to it's default value, even if the Hotel has already been reserved...

BTW, all of the code is functioning, it is just the state that is giving me a problem...

I've been troubleshooting and debugging the code for a couple of hours but nothing concrete so far.

I've included code from most of the files, but I can't bring in the code from all of the ones needed, or it wouldn't quite be an "minimal" reproducible example, so I'll try to summarize the structure here:

There is a many-to-many relationship between Users and Hotels, which has Bookings belonging to both. This enables me to use hotel.users, etc.

I've just tried adding in a new state (const [bookingObject, setBookingObject] = useState();), but I haven't been able to get it to give me a truthy value 100% of the time... Can anyone see what it is that I'm doing wrong? Anyone have any suggestions or ideas?

bookings_controller.rb:

class BookingsController < ApplicationController
    skip_before_action :authorize, only: [:create, :destroy]

    def show
        render json: @booking
    end

    def create
        booking = Booking.new(booking_params)
        if booking.save
            render json: booking, status: :created
        else
            render json: {errors: "Something went wrong!"}
        end
    end

    def destroy
        @booking = Booking.find(params[:id])
        @booking.destroy
    end

    private
    def set_booking
        @booking = Booking.find(params[:id])
    end

    def booking_params
        params.require(:booking).permit(:id, :user_id, :hotel_id)
    end
end

hotels_controller.rb:

    class HotelsController < ApplicationController
        skip_before_action :authorize, only: [:create, :destroy]
        def index
            render json: Hotel.all
        end

        def show
            render json: @hotel
        end

        def hotel_params
            params.require(:hotel).permit(:name, :city, :country, :company)
        end
    end

Hotel.jsx:

    import React, {useContext, useState} from 'react';
      const {bookings, setBookings} = useContext(BookingsContext);
      const [booked, setBooked] = useState(false);
      const [bookingObject, setBookingObject] = useState();

    function toggleBooking(e){
      if(booked){
        const booking = bookings.find(booking => {return booking.hotel.id == e.target.id});
        deleteBookings(booking.id);
        setBooked(!booked);
      } else if(booked === false){
        postBookings();
        setBooked(!booked);
      }
    }

    function postBookings(){
      const newBooking={
        user_id: (currentUser.id),
        hotel_id: (hotel.id)
      }
      fetch(`http://localhost:3001/users/${currentUser.id}/bookings`, {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify({
          booking: newBooking
        }),
      }).then((r) => r.json())
      .then((data) => {
        setBookingObject(data);
        setBookings([...bookings, data]);
      })
    }

    function deleteBookings(bookingId){      fetch(`http://localhost:3001/users/${currentUser.id}/bookings/${bookingId}`, {
        method: "DELETE"
      })
      .then((r) => {
        if(r.ok)onDeleteBookings(bookingId);
      })
    }

    function onDeleteBookings(deletedBooking){
      const updatedBookings = bookings.filter((booking) => booking.id !== deletedBooking.id);
      setBookings(updatedBookings);
      setBookingObject();
    }

    return(
      <div id='hotels'>
        <p>{hotel.name}</p><p>{hotel.city}, {hotel.country}</p>
        <button id={hotel.id} onClick={toggleBooking} >{booked ? ("Booked") : ("Book Now")}</button>
      </div>
    );
  }

  export default Hotel;
0 Answers
Related