0

I am trying within the changeEventStatus function to add an isJoined attribute to true or false, depending on whether the user is already in that event or not. What I have thought of doing so far is to first filter between 2 arrays and then go through and compare the element of the original array versus the element of the filtered array using a condition.

The problem is that while the conditional works, it only takes 1 element as true and adds the attribute as true leaving all other elements in the array as false. In the filtered array there are 2 objects so it should return an array with 2 true elements within its attributes.

// React
import React, { useEffect, useState } from "react";

// Chakra-ui
import {
  SimpleGrid,
  Box,
  Center,
  Text,
  Stack,
  Button,
  Spinner,
  Flex,
  useToast,
} from "@chakra-ui/react";

// Supabase
import { supabase } from "../../client";

const EventCard = () => {
  const toast = useToast();
  const [events, setEvents] = useState([]);
  const [isJoining, setIsJoining] = useState(false);
  const [eventId, setEventId] = useState(null);

  useEffect(() => {
    getEvents();
    changeEventStatus();
  }, []);

  const getEvents = async () => {
    const { data, error } = await supabase.from("events").select("*");
    setEvents([...events, ...data]);
  };

  const toaster = () => {
    return toast({
      title: "¡Event Message!",
      description: "You already participate in this event.",
      status: "error",
      duration: 3000,
      isClosable: true,
    });
  };

  const isUserParticipateInEvent = async (userId, eventId) => {
    let { data: event_participants, error } = await supabase
      .from("event_participants")
      .select("*")
      .eq("participant_id", userId)
      .eq("event_id", eventId);
    if (event_participants.length > 0) {
      return true;
    } else {
      return false;
    }
  };

  const joinToEvent = async (id) => {
    const user = supabase.auth.user();
    let userId = user.id;
    let eventId = Number(id);

    setEventId(id);

    const participant = {
      participant_id: userId,
      event_id: eventId,
    };

    let isParticipating = await isUserParticipateInEvent(userId, eventId);

    if (!isParticipating) {
      try {
        setIsJoining(true);
        const { data, error } = await supabase
          .from("event_participants")
          .insert([participant]);
        if (error) {
          console.log(error);
        }
      } catch (err) {
        console.log("Error trying to join the event ", err);
      } finally {
        setIsJoining(false);
      }
    } else {
      toaster();
    }
  };

  const changeEventStatus = async () => {
    // The problem
    const user = supabase.auth.user();
    const userId = user.id;
    const { data: event_participants, error } = await supabase
      .from("event_participants")
      .select("*")
      .eq("participant_id", userId);

    const { data: eventData, error: dataError } = await supabase
      .from("events")
      .select("*");

    let eventParticipantIds = event_participants.map((ep) => ep.event_id);
    let filteredEvents = eventData.filter((event) =>
      eventParticipantIds.includes(event.id)
    );
    console.log("filtered ", filteredEvents);

    eventData.map((evt) => {
      filteredEvents.map((filteredEvent) => {
        console.log("filt ", filteredEvent.id);
        console.log("event ", evt.id);
        console.log(filteredEvent.id === evt.id);
        if (filteredEvent.id === evt.id) {
          evt["isJoined"] = true;
        } else {
          evt["isJoined"] = false;
        }
      });
    });

    console.log("new event data to render", eventData);
  };

  return events.map((event, ix) => {
    return (
      <Box
        key={ix}
        p={4}
        rounded="sm"
        border="1px"
        borderColor="gray.100"
        boxShadow={"sm"}
      >
        <SimpleGrid
          display="flex"
          alignItems="center"
          justifyContent="space-between"
          columns={2}
        >
          <Box>
            <Stack>
              <Text fontSize={"2xl"} fontWeight="600">
                {event.title}
              </Text>
              <Text>
                {event ? event.description : "No description provided"}
              </Text>
              <Text>{`Organizer: ${event?.creator}`}</Text>
            </Stack>
            <Box pt={4}>
              <SimpleGrid columns={{ sm: 1, md: 2 }}>
                <Box>
                  <Text fontSize={"small"}>{`20 participants`}</Text>
                </Box>
                <Box>
                  <Text fontSize={"small"}>{`Date: ${event.start_date}`}</Text>
                </Box>
              </SimpleGrid>
            </Box>
          </Box>
          <Box>
            <Button bg="green.200" onClick={(e) => joinToEvent(event.id)}>
              {isJoining && eventId === event.id ? "Joining..." : "Join"}
            </Button>
          </Box>
          <Box>{isJoining && eventId === event.id && <Spinner />}</Box>
        </SimpleGrid>
      </Box>
    );
  });
};

export default EventCard;

Example:

const arr1 = [{
    "id": 82,
    "user_id": "e31cb09b-7a63-4581-9e3c-19f4730641bc",
    "title": "Nuevo evento",
    "description": "en estos dias",
    "created_at": "2022-09-17T20:42:42.452948+00:00",
    "updated_at": "2022-09-17T20:42:42.452948+00:00",
    "start_date": "2022-09-23",
    "end_date": null,
    "longitude": -32.9296,
    "latitude": -71.2944,
    "creator": "[email protected]",
    "place_name": null
  },
  {
    "id": 95,
    "user_id": "e31cb09b-7a63-4581-9e3c-19f4730641bc",
    "title": "Virginia",
    "description": null,
    "created_at": "2022-09-17T21:13:40.728779+00:00",
    "updated_at": "2022-09-17T21:13:40.728779+00:00",
    "start_date": "2022-09-17",
    "end_date": null,
    "longitude": 35.4867,
    "latitude": 101.902,
    "creator": "[email protected]",
    "place_name": null
  },
  {
    "id": 96,
    "user_id": "e31cb09b-7a63-4581-9e3c-19f4730641bc",
    "title": "3",
    "description": null,
    "created_at": "2022-09-17T21:19:52.677742+00:00",
    "updated_at": "2022-09-17T21:19:52.677742+00:00",
    "start_date": "2022-09-17",
    "end_date": null,
    "longitude": -10.1511,
    "latitude": -75.3111,
    "creator": "[email protected]",
    "place_name": null
  },
  {
    "id": 97,
    "user_id": "e31cb09b-7a63-4581-9e3c-19f4730641bc",
    "title": "event",
    "description": "At indonesia beach",
    "created_at": "2022-09-17T21:34:53.360125+00:00",
    "updated_at": "2022-09-17T21:34:53.360125+00:00",
    "start_date": "2022-09-17",
    "end_date": null,
    "longitude": -6.17555,
    "latitude": 106.827,
    "creator": "[email protected]",
    "place_name": "Indonesia"
  }
]

const arr2 = [{
    "id": 82,
    "user_id": "e31cb09b-7a63-4581-9e3c-19f4730641bc",
    "title": "Nuevo evento",
    "description": "en estos dias",
    "created_at": "2022-09-17T20:42:42.452948+00:00",
    "updated_at": "2022-09-17T20:42:42.452948+00:00",
    "start_date": "2022-09-23",
    "end_date": null,
    "longitude": -32.9296,
    "latitude": -71.2944,
    "creator": "[email protected]",
    "place_name": null
  },
  {
    "id": 95,
    "user_id": "e31cb09b-7a63-4581-9e3c-19f4730641bc",
    "title": "Virginia",
    "description": null,
    "created_at": "2022-09-17T21:13:40.728779+00:00",
    "updated_at": "2022-09-17T21:13:40.728779+00:00",
    "start_date": "2022-09-17",
    "end_date": null,
    "longitude": 35.4867,
    "latitude": 101.902,
    "creator": "[email protected]",
    "place_name": null
  }
]

arr1.map((evt) => {
  arr2.map((filteredEvent) => {

    if (filteredEvent.id === evt.id) {
      evt['isJoined'] = true;
    } else {
      evt['isJoined'] = false;
    }
  })
});

console.log(arr1);

1 Answer 1

1

The problem is your nested loop. On each pass, it sets all but one element's isJoined to false.

You can simplify this greatly using the following

const eventParticipantIds = new Set(
  event_participants.map((ep) => ep.event_id)
);

const transformedEventData = eventData.map((evt) => ({
  ...evt,
  isJoined: eventParticipantIds.has(evt.id),
}));

A Set is optimised for value lookups so it performs better than an array.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow thanks bro, very useful Set object!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.