Exbaby
Exbaby

Reputation: 75

Cannot read property 'setState' and TypeError: this.props.items.map is not a function with Axios and Reactjs

As I show all Items in the database with Axios and Reactjs, already that if I show it by console if it shows them, but if I want to show in the view does not allow me and I get an error.

ERROR:

TypeError: Cannot read property 'setState' of undefined

In this Line:

        this.setState({ items: response });

CODE:

export default class Body extends Component{
        constructor(props) {
            super(props)
            this.state = {items: [], item: '' }
            this.updateItems = this.updateItems.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
        }

        loadItems() {

            axios.get('/api/v1/items.json')
                .then(function (response) {
                this.setState({ items: response });
             })
                .catch(function (error) {
                console.log(error);
             });
        }

        handleSubmit(item) {
            var newState = this.state.items;
            newState.push(item);
            this.setState({ items: newState })
        }

        handleDelete(id) {
            $.ajax({
                url: `/api/v1/items/${id}`,
                type: 'DELETE',
                success:() => {
                    this.removeItemClient(id);
                }
            });
        }

        removeItemClient(id) {
            var newItems = this.state.items.filter((item) => {
                return item.id != id;
        });

        this.setState({ items: newItems });
        }

        handleUpdate(item) {
            $.ajax({
                    url: `/api/v1/items/${item.id}`,
                    type: 'PUT',
                    data: { item: item },
                    success: () => {
                        this.updateItems(item);
                    }
            }
        )}

        updateItems(item) {
            var items = this.state.items.filter((i) => { return i.id != item.id });
            items.push(item);
            this.setState({items: items });
        }

        render() {
            if(this.state.items.length < 1)
            this.loadItems();
            return (
                <div>
                    <NewItem handleSubmit={this.handleSubmit}/>
                    <AllItems  items={this.state.items}  handleDelete={this.handleDelete.bind(this)} onUpdate={this.handleUpdate.bind(this)}/>
                </div>
            )
        }
}

but if I modified this metod to this form:

loadItems() {
            //var self = this;
            //self.setState
            axios.get('/api/v1/items.json')
                .then(function (response) {
                this.setState({ items: response });
             }.bind(this))
                .catch(function (error) {
                console.log(error);
             });
        }

the error 'setState' is removed, but other error is shown:

this error:

TypeError: this.props.items.map is not a function

in this line:

var items= this.props.items.map((item) => {

this is the code of present line:

export default class AllItems extends Component{
    constructor(props){
        super(props);
        this.onUpdate = this.onUpdate.bind(this);
    }
     handleDelete(id) {
        this.props.handleDelete(id);
    }

    onUpdate(item) {
        this.props.onUpdate(item);
    }

    render() {
            var items= this.props.items.map((item) => {
                return (
                    <div key={item.id}>
                        <Item item={item}
                              handleDelete={this.handleDelete.bind(this, item.id)}
                              handleUpdate={this.onUpdate}/>
                    </div>
                )
            });

        return(
            <div>
                {items}
            </div>
        )
    }
}

Upvotes: 1

Views: 143

Answers (2)

Exbaby
Exbaby

Reputation: 75

loadItems() {
            //var self = this;
            //self.setState
            axios.get('/api/v1/items.json')
                .then(function (response) {
                this.setState({ items: response.data });
             }.bind(this))
                .catch(function (error) {
                console.log(error);
             });
        }

this line is the answer for resolving the error.

this.setState({ items: response.data });

I need add data At the end of response.

Upvotes: 0

A. L
A. L

Reputation: 12639

Change:

.then(function (response) {
    this.setState({ items: response });
})

to

.then( (response) => {
    this.setState({ items: response });
})

Otherwise, function is referencing the caller and not what you're expecting.

Read up fat arrows or arrow function.

Upvotes: 1

Related Questions