Monday, 22 February 2021

Save a favorite icon when a user logs out or refreshes the page, react, mern stack

Good morning everyone, I have a button component that controls whether or not the user wants to make something a favorite or not. Everything works like it should, as long as I don't log out or refresh the page.

I feel like I know the logic of how to implement this, but I can't seem to figure out how to do it.

I have the array of favorites saved in local storage, as well as in my database. How would I go about setting the state of the button to be clicked or not on initial render?

here is the code for my button.

export default function FavoriteButton({
  _id,
  title,
  artist,
  rating,
  genre,
  description,
}) {
  //state for favorites
  const [click, handleClick] = React.useState(false);

  const [favorite, setFavorite] = React.useState([]);

  //get favorites

  const fetchData = async () => {
    const result = await axios.get(
      "http://localhost:5000/favorite/get",
      authToken
    );

    setFavorite(result);
  };

  React.useEffect(() => {
    fetchData();
  }, []);

  //add favorites
  const addFavorites = () => {
    const favorites = {
      userId: _id,
      title,
      artist,
      rating,
      genre,
      description,
    };

    axios
      .post("http://localhost:5000/favorite/add", favorites, authToken)
      .then((response) => {
        setFavorite(response);
      });

    fetchData();
    localStorage.setItem("favorite", JSON.stringify(favorite));

    handleClick(true);
  };

  // delete favorite

  const deleteFavorite = async () => {
   await axios.delete("http://localhost:5000/favorite/delete", {
      data: { title: title },
      authToken,
    });

    handleClick(false);
  };

  const classes = buttonStyles();

  return (
    <div>
      {click === false ? (
        <IconButton onClick={addFavorites} className={classes.favoriteOff}>
          {" "}
          <StarOutlineIcon className={classes.favoriteGrey} />{" "}
        </IconButton>
      ) : (
        <IconButton onClick={deleteFavorite} className={classes.favoriteOn}>
          {" "}
          <StarRateIcon className={classes.favoriteYellow} />
        </IconButton>
      )}
    </div>
  );
}

I am mapping over data in another component and show the button there.

I have added the parent component here

export default function ShowRecords() {
  const classes = recordFormStyles();
  const url = " http://localhost:5000/record";

  //get userData state to use in useEffect

  //set state for showing records in database and opening/closing modals

  const [newRecords, newRecordData] = React.useState([]);

  const [editOpen, handleEditModal] = React.useState(false);

  const [addModalOpen, handleAddModal] = React.useState(false);

  //set state for edit records

  const [title, setTitle] = React.useState("");

  const [artist, setArtist] = React.useState("");

  const [rating, setRating] = React.useState("");

  const [genre, setGenre] = React.useState("");

  const [description, setDescription] = React.useState("");

  const [userId, setUserId] = React.useState("");

  //set state for favorite icon

  //functions to control state

  const handleAddModalOpen = () => {
    handleAddModal(true);
  };

  const handleCloseAddModal = () => {
    handleAddModal(false);
  };

  const handleIsEditModalClose = () => {
    handleEditModal();
  };

  //fetch record data

  const fetchData = async () => {
    const result = await axios.get(
      "http://localhost:5000/record/get",
      authToken
    );
    newRecordData(result.data);
  };

  React.useEffect(() => {
    fetchData();
  }, []);

  // delete records

  const deleteRecord = async (_id) => {
    const deleteRecords = {
      _id: _id,
    };

    await axios
      .delete("http://localhost:5000/record/" + _id, deleteRecords)
      .then((result) => {
        const refresh = newRecords.filter((result) => result._id !== _id);
        newRecordData(refresh);
      });
  };

  //functions for controlling edit record state

  const editRecord = (_id, title, artist, rating, genre, description) => {
    setUserId(_id);
    setTitle(title);
    setArtist(artist);
    setRating(rating);
    setGenre(genre);
    setDescription(description);
    handleEditModal(true);

    console.log(title);
  };

  //functions for setting favorite state and color and post request to add favorite

  return (
    <div>
      {/* set props */}

      <Favorites />
      <AddRecord
        isAddModalOpen={addModalOpen}
        handleIsAddModalClose={handleCloseAddModal}
        addNewRecords={newRecords}
        handleIsAddModalOpen={handleAddModal}
        refreshRecordData={newRecordData}
      />
      <EditRecords
        editModalOpen={editOpen}
        handleCloseEditModal={handleIsEditModalClose}
        editUserId={userId}
        editTitle={title}
        editArtist={artist}
        editRating={rating}
        editGenre={genre}
        editDescription={description}
        editTitleState={setTitle}
        editArtistState={setArtist}
        editRatingState={setRating}
        editGenreState={setGenre}
        editDescriptionState={setDescription}
        editUrl={url}
        editFetchData={fetchData}
        editNewRecordData={newRecordData}
      />
      <Button
        className={classes.addButton}
        onClick={() => handleAddModalOpen(true)}
      >
        Add Record
      </Button>

      <div className={classes.cardsContainer}>
        <Grid container spacing={10} style=>
          {newRecords.length > 0 &&
            newRecords.map((element) => (
              <Grid key={element._id} item xs={12} sm={6} md={4} lg={4} xl={2}>
                <Card className={classes.root}>
                  <CardContent>
                    <>
                      <FavoriteButtonRecord
                        key={element._id}
                        title={element.title}
                        artist={element.artist}
                        rating={element.rating}
                        genre={element.genre}
                        description={element.description}
                      />
                    </>
                    <Typography gutterBottom variant="h6">
                      {element.title}
                    </Typography>
                    <Typography variant="body2" color="inherit" component="p">
                      Artist: {element.artist}
                    </Typography>
                    <Typography variant="body2" color="inherit" component="p">
                      Label: {element.rating}
                    </Typography>
                    <Typography variant="body2" color="inherit" component="p">
                      Genre: {element.genre}
                    </Typography>
                    <Typography variant="body2" color="inherit" component="p">
                      Description: {element.description}
                    </Typography>
                  </CardContent>

                  <CardActions>
                    <Button
                      onClick={() =>
                        editRecord(
                          element._id,
                          element.title,
                          element.artist,
                          element.rating,
                          element.genre,
                          element.description
                        )
                      }
                      size="small"
                      color="inherit"
                      className = {classes.button}
                    >
                      Edit
                    </Button>
                    <Button
                      onClick={() =>
                        deleteRecord(
                          element._id,
                          element.title,
                          element.artist,
                          element.rating,
                          element.genre,
                          element.description
                        )
                      }
                      size="small"
                      color="inherit"
                      className = {classes.button}
                    >
                      Delete
                    </Button>
                  </CardActions>
                </Card>
              </Grid>
            ))}
        </Grid>
      </div>
    </div>
  );
}

let me know if I need to show that code as well. Thank you in advance!



from Save a favorite icon when a user logs out or refreshes the page, react, mern stack

No comments:

Post a Comment