Yair Rachum
Yair Rachum

Reputation: 1

make follow and unfollow button in react(changing button)

This is my code, I used Map to render the vacations cards and I need to add follow and unfollow functionality. I want it to change after I press on "Follow" change it to "Unfollow" on one card only. if anyone can help me it would be much appreciated.

export default function Vacations(){
    
    const [vacationsArray, setVacationsArray] = useState<IVacation[]>([]);
    const userDetails = useSelector((state: AppState) => state.userDetailes);


    useEffect(() => {
        axios.get("http://localhost:3001/vacations/")
        .then(data => {
            setVacationsArray(data.data)
            console.log(data.data)
        }).catch(e =>{
            console.log("failed to fetch data" + e)
        })
    },[]);

    const onUnfollowClicked = async()=>{
        console.log("Unfollowed")
    }

    const onFollowClicked = async (vacationId:any) =>{
        let userId = userDetails[0].id;
        await axios.post(`http://localhost:3001/followedVacations/${vacationId}`, {vacationId, userId});
      }

    return(
        <div className="vacationsContainer">
                {vacationsArray.map((vacation:any, key:number) =>(
                    <div key={key} className="vacation">
                        <button onClick={()=>onFollowClicked(vacation.id)}>Follow</button>
                        <button onClick={()=>onUnfollowClicked}>Unfollow</button>
                        <h1>{vacation.destination}</h1> <br></br>
                        <img width="300px" height="300px" src={vacation.image} alt="" /> <br></br>
                        <h3>Description:  <span>{vacation.description}</span></h3> <br></br>
                        <h3>Price:  <span>{vacation.price}$</span></h3> <br></br>
                        <h3>From:  <span>{vacation.startDate}</span></h3> <br></br> 
                        <h3>To:  <span>{vacation.endDate}</span></h3>
                    </div>
                ))}
        </div>
    )
}

Upvotes: 0

Views: 877

Answers (1)

Kevin Haxhi
Kevin Haxhi

Reputation: 498

One approach would be to store all subscribers' ids (ids of users that have followed) on each of the vacation objects, on the backend:

// Example solution, assuming there is an array of users that subscribed
// for each vacation (e.g.
// {
//   id: '',
//   image: '',
//   description: '',
//   price: '',
//   startDate: '',
//   endDate: '',
//   subscribers: ['id1', 'id2', 'id4', ...]
// })

return (
  <div className="vacationsContainer">
    {vacationsArray.map((vacation: any, key: number) => {
      let onClickFunction = null;
      let buttonText = "";

      if (
        vacation?.subscribers.length &&
        vacation.subscribers.includes(userDetails[0].id)
      ) {
        onClickFunction = () => onUnfollowClicked(vacation.id);
        buttonText = "Unfollow";
      } else {
        onClickFunction = () => onFollowClicked(vacation.id);
        buttonText = "Follow";
      }

      return (
        <div key={key} className="vacation">
          <button onClick={onClickFunction}>{buttonText}</button>
          <h1>{vacation.destination}</h1> <br></br>
          <img width="300px" height="300px" src={vacation.image} alt="" />
          <br></br>
          <h3>
            Description: <span>{vacation.description}</span>
          </h3>
          <br></br>
          <h3>
            Price: <span>{vacation.price}$</span>
          </h3>
          <br></br>
          <h3>
            From: <span>{vacation.startDate}</span>
          </h3>
          <br></br>
          <h3>
            To: <span>{vacation.endDate}</span>
          </h3>
        </div>
      );
    })}
  </div>
);

If all you want is to have a couple of buttons that switch from "Follow" to "Unfollow" and vice versa on click, then you just need to store an array of followedVacationIds on your local state, and add or remove vacation ids from it when each specific button is clicked.

I can't determine what you are looking for just from the information you have provided. Hopefully the code I implemented above is the right approach to your problem. Otherwise, please edit your question with a bit more information, for example the structure of the data you are fetching and I will edit my answer with a proper solution.

Upvotes: 1

Related Questions