0

I am trying to update the state of a component with ReactJS but getting the following error. Error and code provided below.

Potentially unhandled rejection [1] TypeError: Cannot read property 'setState' of undefined

import React from 'react';
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table';

var rest, mime, client;

rest = require('rest');
mime = require('rest/interceptor/mime');

import ParameterDialog from './parameter-dialog';

const parameterTypes = {
    'STRING': 'STRING',
    'BOOLEAN': 'BOOLEAN',
    'INTEGETR': 'INTEGETR',
    'DECIMAL': 'DECIMAL'
};

const categoryAvailable = {
    'POS': 'POS'
};

const options = {
    noDataText: 'No parameters founds.'
}

function enumFormatter(cell, row, enumObject) {
    return enumObject[cell];
}

export default class ParameterContainer extends React.Component {

    constructor(props) {
        super(props);
        this.state = { parameters: [] };
        this.client = rest.wrap(mime);
    }

    fetchFromApi() {
        this.client({ path: '/api/parameters' }).then(function(response) {
            this.setState({parameters: response});
        });
    }

    componentDidMount() {
        this.fetchFromApi();
    }

    render() {
        return (
            <div>
                <h2>Parameters</h2>
                <ParameterDialog />
                <BootstrapTable data={this.state.parameters} options={options} pagination>
                    <TableHeaderColumn isKey dataField='id'>ID</TableHeaderColumn>
                    <TableHeaderColumn dataField='category' filterFormatted dataFormat={enumFormatter} formatExtraData={categoryAvailable}
                        filter={{type: 'SelectFilter', options: categoryAvailable}}>Category</TableHeaderColumn>
                    <TableHeaderColumn dataField='subCategory'>Sub Category</TableHeaderColumn>
                    <TableHeaderColumn dataField='parameter' filter={ { type: 'TextFilter', delay: 500 } }>Parameter</TableHeaderColumn>
                    <TableHeaderColumn dataField='type' filterFormatted dataFormat={enumFormatter} formatExtraData={parameterTypes}
                                       filter={{type: 'SelectFilter', options: parameterTypes}}>Type</TableHeaderColumn>
                    <TableHeaderColumn dataField='roles'>Roles</TableHeaderColumn>
                </BootstrapTable>
            </div>
        )
    }
}
3
  • Please search before asking questions Commented Feb 19, 2017 at 20:04
  • if you're using babel you can use babeljs.io/docs/plugins/transform-es2015-arrow-functions and then you don't need to bind your arrow functions anymore Commented Apr 16, 2017 at 19:00
  • while using 'this' keyword in callback we need make sure who is calling this callback. Here To acess the lexical scope you need to arrow function or you can bind the function. For better understanding you can look into lexical scope and Dynamic scope Commented Feb 19, 2019 at 9:51

3 Answers 3

0

You need to use arrow function if you are using stage-0 babel transpiler.

class ParameterContainer{
  fetchFromApi = () => {

  }
}

otherwise you can bind fetchFromApi function in constructor to this.

constructor(){
   this.fetchFromApi = this.fetchFromApi.bind(this)
}
Sign up to request clarification or add additional context in comments.

2 Comments

This question is a duplicate, and this is the wrong answer. The .then callback needs binding, not the method.
@AndyRay user can also save the context of this in that rather than binding.
0

Problem seems to be with changing context of this, you created Promise and and trying to change its state. this.fetchFromApi.bind(this)

Comments

-1

Edited my answer:

if you're using babel you can use https://babeljs.io/docs/plugins/transform-es2015-arrow-functions/ and then you don't need to bind your arrow functions anymore

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.