React js TypeError: Cannot read properties of undefined (reading 'setState')

So i have problem with setting state for class component while using websockets.
picture of problem
it’s seems like my backend works fine and problem is on the frontend side.
I’m new to react so i don’t know how the fix the problem here.

and data ‘jsonBody’ is delivering the right information we need aswell. so i guess the only problem is with for setting state for this.state.users list.
frontend code:

class Users extends React.Component {

    // Constructor
    constructor(props) {
        super(props);
        this.state = {
            users: []
        }
        this.deleteUsers = this.deleteUsers.bind(this);
        this.editUsers = this.editUsers.bind(this);
        this.addUsers = this.addUsers.bind(this);

    }

    componentDidMount(){
        fetch("http://localhost:8080/users")
            .then(response => {
                return response.json()
            })
            .then(data => {
                this.setState({users: data})
            })
        const SOCKET_URL = 'ws://localhost:8080/ws-message';
        let onConnected = () => {
            console.log("Connected!!")
            client.subscribe('/topic/message', function (msg) {
                if (msg.body) {
                    var jsonBody = JSON.parse(msg.body);
                    this.setState({users: this.state.users.concat(jsonBody) });
                }
            });
        }
        let onDisconnected = () => {
            console.log("Disconnected!!")
        }
        const client = new Client({
            brokerURL: SOCKET_URL,
            reconnectDelay: 5000,
            heartbeatIncoming: 4000,
            heartbeatOutgoing: 4000,
            onConnect: onConnected,
            onDisconnect: onDisconnected
        });
        client.activate();
    }

    addUsers(user) {
        this.setState({users: this.state.users.concat(user) })
    }


    editUsers(user) {
        this.setState({users: this.state.users.map((users) => users.id === user.id ? user : users)})
    }


    deleteUsers(id){
        const api = "http://localhost:8080/users"
        axios.delete(api + "/" + id).then( res => {
            this.setState({users: this.state.users.filter(user => user.id !== id)});
        });
    }


    render() {

        return (
            <div className="container">
                <h1>Manage users</h1>
                <table className="table">
                    <thead>
                    <tr>
                        <th>name</th>
                        <th>username</th>
                        <th>email</th>
                        <th></th>
                    </tr>
                    </thead>
                    <tbody>
                    {this.state.users.map(user =>
                        <tr key={user.id}>
                            <td>{user.name}</td>
                            <td>{user.username}</td>
                            <td>{user.email}</td>
                            <td className="d-flex justify-content-end" ><Example user={user} users={this.state.users} editUsers={this.editUsers} ></Example>
                                <button className="remove btn btn-danger btn-sm  ms-3"  onClick={ () => this.deleteUsers(user.id)}>Remove</button>
                            </td>
                        </tr>
                    )}
                    </tbody>
                </table>
                <Example  users={this.state.users}  addUsers={this.addUsers} />
            </div >
        );
    }
}
export default Users;

backend:

   @PostMapping("/users")
    public List<User> addUsers(@RequestBody User user){
        UserDao.addUser(user);
        template.convertAndSend("/topic/message" ,user);
        return UserDao.showPostedUser();
    }

    @PutMapping("/users/{id}")
    public ResponseEntity<HttpStatus> editUsers(@PathVariable int id,@RequestBody User user){
        UserDao.updateUser(user,id);
        template.convertAndSend("/topic/update", UserDao.showUpdatedUser(id));
        return ResponseEntity.ok(HttpStatus.OK);
    }

    @DeleteMapping("/users/{id}")
    public ResponseEntity<HttpStatus> deleteUsersById(@PathVariable int id){
        UserDao.deleteUserById(id);
        template.convertAndSend("/topic/delete", id);
        return ResponseEntity.ok(HttpStatus.OK);
    }

    @SendTo("/topic/message")
    public User broadcastMessage(@Payload User user) {
        return user;
    }


    @SendTo("/topic/delete")
    public int broadcastDelete(@Payload int id) {
        return id;
    }

    @SendTo("/topic/update")
    public User broadcastUpdate(@Payload User user) {
        return user;
    }
}

>Solution :

Arrow functions and functions are not interchangeable. You lose lexical this of the component when using a function.

            client.subscribe('/topic/message', (msg) => {
                if (msg.body) {
                    var jsonBody = JSON.parse(msg.body);
                    this.setState({users: this.state.users.concat(jsonBody) });
                }
            });

Leave a Reply