1
votes

In console before render() this.state.data1.length is not giving any error but as soon as I use it in view tag this is giving error as : TypeError: undefined is not an object (evaluating '_this.state.data1.length') If I delete this line from view tag then nothing is printed in my reacttable tag and hence I suppose this line is required but what change should I make so that there's no error using react native code and my retrieved data is also printed on my app.

import React, { Component } from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
import ReactTable from 'react-table';
import firebase from 'firebase';

const firebaseConfig = {
...
};
firebase.initializeApp(firebaseConfig);


export default class Form1 extends Component {
constructor(props) {
    super(props);

    this.state = {
        data: [],
        columns: [
            {
                Header: "email",
                accessor: "email"
            },
            {
                Header: "password",
                accessor: "password"
            }
        ]
    }
}

componentDidMount() {
    const data = [];
    const data1 = [];
    var query = firebase.database().ref("/users");
    query.once("value").then((snapshot) => {
      //console.log(snapshot)
        snapshot.forEach((childSnapshot, index) => {

            let singleObj = {
                email: childSnapshot.val().email,
                password: childSnapshot.val().password,
            }

           // console.log('email:',data)
            data.push(singleObj);
           this.setState({data1 : data});
          console.log('sssssssssssssssssss',this.state.data1)
        });
    });
}

submit1=()=>{
console.log(this.state.data1.length)
console.log('data1:',this.state.data1)
}

render() {
    return (
        <View style="styles.container">

            {this.state.data1.length > 0 && <ReactTable data={this.state.data1} columns={this.state.columns} />}
                       <Button title='Submit' onPress={this.submit1.bind(this)} />

        </View>
    );
}
}

const styles = StyleSheet.create({
container: { flex: 1, padding: 16, paddingTop: 30, backgroundColor: '#fff' },
head: { height: 40, backgroundColor: '#f1f8ff' },
text: { margin: 6 }
});
2
You are getting this error because you are component is rendering before the data is updated - Goskula Jayachandra
So according to you what changes should I make for getting proper output? @user12129132 - Vibhuti
You had not declared any state data1 change this to this.state.data.length are you getting the correct data in here console.log('sssssssssssssssssss',this.state.data1) - Goskula Jayachandra
Yes, in console.log('ssssssssssssssssss',this.state.data1) is giving me proper output. Only it is giving error when it is used inside view tag @user12129132 - Vibhuti
this.state = { data: [], is it data1 or data - Goskula Jayachandra

2 Answers

1
votes

Change your code something like this:

import React, { Component } from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
import { Table, Row, Rows } from 'react-native-table-component';


export default class Form1 extends Component {
constructor(props) {
    super(props);

    this.state = {
        data: [],
        tableHead: ['Emails', 'Password'],
        tableData1:[],
    }
}


componentDidMount() {
    var query = firebase.database().ref("/users");
    query.once("value").then((snapshot) => {
        snapshot.forEach((childSnapshot, index) => {
            let singleObj = {
                email: childSnapshot.val().email,
                password: childSnapshot.val().password,
            }
           this.state.data.push(singleObj);
           this.setState({data: this.state.data});
          console.log('sssssssssssssssssss',this.state.data)
        });
        for (var i = 0; i < this.state.data.length; i++) {
            this.state.tableData1[i] = [this.state.data[i].email, this.state.data[i].password];
            this.setState({ tableData1: this.state.tableData1 });
        }

    });
}

submit1=()=>{
console.log(this.state.data.length)
console.log('data1:',this.state.data)
}

render() {
    return (
        <View style={{flex:1,marginTop:100}}>
        {this.state.data.length > 0 &&   
        <Table borderStyle={{borderWidth: 2, borderColor: '#c8e1ff'}}>
        <Row data={this.state.tableHead} />
        <Rows data={this.state.tableData1} />
        </Table>}
      <Button title='Submit' onPress={this.submit1.bind(this)} />

    </View>
    );
}
}

enter image description here

Hope this helps!

0
votes

Your(s) only issues was, uses of data: [] in state instead of data1: []. However I found few more enhancements in your code and below is my suggestions

Issues:

1) data1 being used at render but not initialised in state

2) styles object is used as string instead of object

3) Not an issue, but you don't need to bind _submit as it's already an arrow function

import React, { Component } from 'react';
import { StyleSheet, View, Button } from 'react-native';
import ReactTable from 'react-table';
import firebase from 'firebase';

const firebaseConfig = {};
firebase.initializeApp(firebaseConfig);

const COLUMNS = [
  {
    Header: 'email',
    accessor: 'email',
  },
  {
    Header: 'password',
    accessor: 'password',
  },
];

export default class Form1 extends Component {
  state = {
    data: [],
    columns: COLUMNS,
  };

  componentDidMount() {
    const data = [];
    const query = firebase.database().ref('/users');

    query.once('value').then(snapshot => {
      snapshot.forEach((childSnapshot, index) => {
        const singleObj = {
          email: childSnapshot.val().email,
          password: childSnapshot.val().password,
        };

        data.push(singleObj);
        this.setState({ data });
      });
    });
  }

  _submit = () => {
    console.log('data1:', this.state.data);
  }

  render() {
    const { data, columns } = this.state;

    return (
      <View style={styles.container}>
        {data.length > 0 && <ReactTable data={data} columns={columns} />}
        <Button title="Submit" onPress={this._submit} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 16, paddingTop: 30, backgroundColor: '#fff' },
  head: { height: 40, backgroundColor: '#f1f8ff' },
  text: { margin: 6 },
});