AS10
AS10

Reputation: 271

Update only one Object Key Reactjs

Good evening, I have an object that I am sending a PUT to my API to update book information. I want to be able to only send one property to the API and have the rest persist. As of right now they are set to undefined if you only set one property, you have to update all 3 for it to work. The below code is the re-usable component, this component is made for every book that is stored in the API.

Book.js

import React, { useState } from "react";
import {
    deleteBook,
    updateBook
  } from '../api/books';

// Material UI
import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';
import Stack from '@mui/material/Stack';

const Book = ({setBooks, bookId, bookTitle, bookStart, bookEnd}) => {

    // State to update an existing books data
  const [updateNewBookTitle, setNewUpdateBookTitle] = useState("");
  const [updateNewBookStart, setNewUpdateBookStart] = useState("");
  const [updateNewBookEnd, setNewUpdateBookEnd] = useState("");

    // Delete a specific book
    const onDeleteBook = async (id) => {
        const responseStatus = await deleteBook(id);
    
        if (responseStatus !== 200) {
          alert("Deleting failed");
          return;
        }
    
        setBooks((previousBooks) =>
          previousBooks.filter((book) => book.id !== id)
        );
      };
    
      // Update a previous book
      const onUpdateBook = async (id, newTitle, newStart, newEnd) => {
        const responseStatus = await updateBook(id, newTitle, newStart, newEnd);
    
        if (responseStatus !== 200) {
          alert("Updating failed");
          return;
        }
    
        setBooks((previousBooks) => {
          const nextBooksState = [...previousBooks];
          const bookToUpdate = nextBooksState.find(
            (book) => book.id === id
          );
    
          bookToUpdate.title = newTitle;
          bookToUpdate.start = newStart;
          bookToUpdate.end = newEnd;


         
    
          return nextBooksState;
        });
      };
    
    return (
        <form onSubmit={() => {onUpdateBook(bookId, updateNewBookTitle, updateNewBookStart, updateNewBookEnd)}}>
          <Stack key={bookId}>
          <TextField id="standard-basic"
                     label="Title"
                     defaultValue={bookTitle}
                     variant="standard"
                     onChange={e => setNewUpdateBookTitle(e.target.value)}
          />
          <TextField id="standard-basic"
                     label="Start Date"
                     defaultValue={bookStart}
                     variant="standard"
                     onChange={e => setNewUpdateBookStart(e.target.value)}
          />
          <TextField id="standard-basic"
                     label="End Date"
                     defaultValue={bookEnd}
                     variant="standard"
                     onChange={e => setNewUpdateBookEnd(e.target.value)}
          />
          <Button variant="contained"
                  color="success"
                  type="submit"
          >
            Update Book
          </Button>
          <Button variant="contained"
                  color="error"
                  onClick={() => {onDeleteBook(bookId)}}
          >
            Delete Book
          </Button>
        </Stack>
        </form>
        
      )
}
export default Book;

Upvotes: 0

Views: 428

Answers (1)

Deniz Karadağ
Deniz Karadağ

Reputation: 761

Updating the database will be directly related to your backend function. Because you want to send only one property or lets say not the entire object with full info, so your server PUT request should handle that part. I think there can be 2 options to achieve what you want:

  1. Retrieve all book information into the component and make a PUT request with existing&updated data in the same object.
  2. Send only the updated information to your server function and add a if/switch or any other condition case which checks if your request object contains full data columns in database. if it's false, then you still fetch the relevant book data, use spread operator and only update the relevant key. Like: requestObject = { ...existingBookData, updatedData}

I hope it makes sense

Upvotes: 2

Related Questions