reactjsapiaxiosreact-hooksjsonplaceholder

Not able to perform PUT request in my react js application


I'm working on the CRUD operations that are to be performed in an application using JSON placeholder API. I want to update the data of the API using the PUT request and display it back on my front end. I'm actually fetching the data from the users endpoint. I'm not able to perform the PUT request and I'm not understanding whether or not to set the array after performing the PUT request. I keep getting an error that is: userData.map() is not a function after clicking on save changes. I know that I'm setting a single object to the array after the fetching operation which is logically incorrect. I'm using Axios at present, also used fetch(), but no use. Nothing works! Please help me out with this one. I'm attaching the code below. "handleSave" is the function where I'm performing the changes.

Thank you very much in advance!

    import React, { useState, useEffect } from 'react';
    import { v4 as uuidv4 } from 'uuid';
    import axios from 'axios';

    function Table() {

    const [userData, setUserData] = useState([]);
    const [clickOnEdit, setClickOnEdit] = useState(false);
    const [index, setIndex] = useState("");
    const [name, setName] = useState("")
    const [username, setUsername] = useState("")
    const [email, setEmail] = useState("")
    const [phone, setPhone] = useState("")
    const [website, setWebsite] = useState("")

    useEffect(() => {
        axios.get("https://jsonplaceholder.typicode.com/users").then((res) => {
        setUserData(res.data);
    })
    },[])

    const handleAddRow = () => {
        setUserData([...userData, 
            {
                id: uuidv4(), 
                name: "name", 
                username: "username",
                email: "email",
                phone: "phone",
                website: "website"
            }
        ])
    }

    const handleDelete = (item) => {
        const id = item;
        setUserData(userData.filter((individualItem) => individualItem.id !== id));
    }

    const handleEdit = (item) => {
        const id = item;
        setIndex(id);
        setClickOnEdit(true);
    }


    const handleSave = (item) => {

        setClickOnEdit(false);
        axios.put(`https://jsonplaceholder.typicode.com/users/${item}`,
        {
            name: name, 
            username: username, 
            email: email, 
            phone: phone, 
            website: website
        })
        .then((res) => {
            setUserData(res.data);
        })
    }

    return (
        <div>
            <div>
                <table>
                    <tr>
                        <th>Name</th>
                        <th>Username</th>
                        <th>Email</th>
                        <th>Phone</th>
                        <th>Website</th>
                    </tr>
                </table>
            </div>
            <button onClick={(e) => handleAddRow(e)}>Add row</button>
            {userData.map((items, id) => (
                <div key={id} >
                    <table>
                        <tr>
                            {clickOnEdit ? 
                                <div>
                                    {index === id ?
                                    <div>
                                        <td><input value={name} name="name" onChange={(e) => setName(e.target.value)} /></td>
                                        <td><input value={username} name="username" onChange={(e) => setUsername(e.target.value)} /></td>
                                        <td><input value={email} name="email" onChange={(e) => setEmail(e.target.value) } /></td>
                                        <td><input value={phone} name="phone" onChange={(e) => setPhone(e.target.value)} /></td>
                                        <td><input value={website} name="website" onChange={(e) => setWebsite(e.target.value)} /></td>
                                        <button onClick={() => handleSave(items.id)} >Save entry</button>
                                    </div>
                                    :
                                    <div>
                                        <td>{items.name}</td>
                                        <td>{items.username}</td>
                                        <td>{items.email}</td>
                                        <td>{items.phone}</td>
                                        <td>{items.website}</td>
                                        <button onClick={(e) => handleEdit(items.id, e)} >Edit</button>
                                        <button onClick={() => handleDelete(items.id)}>Delete</button>
                                    </div>
                                    }
                                </div>
                                :
                                <div>
                                    <td>{items.name}</td>
                                    <td>{items.username}</td>
                                    <td>{items.email}</td>
                                    <td>{items.phone}</td>
                                    <td>{items.website}</td>
                                    <button onClick={(e) => handleEdit(items.id, e)} >Edit</button>
                                    <button onClick={() => handleDelete(items.id)}>Delete</button>
                                </div>
                            }
                        </tr> 
                    </table>
                </div>
            ))}
        </div>
    )
}

export default Table;

Solution

  • The response you will get is an object, so try to replace that id with the res object.

     const handleSave = (item) => {
    
            setClickOnEdit(false);
            axios.put(`https://jsonplaceholder.typicode.com/users/${item}`,
            {
                name: name, 
                username: username, 
                email: email, 
                phone: phone, 
                website: website
            })
            .then((res) => {
              setUserData(
                userData.map((user) =>
                  user.id === res.data.id - 1 ? res.data : user
                )
              );
            })
        }