1

I am new to React Native and struggling a little to get this working. I have realtime database in Firebase which contains 'mechanic' names. I would like to retrieve these names and display them in a list.

enter image description here

I would like to display this data in a list and then execute some function when the user clicks on either name. I thought adding the database data to an array then looping through the array to add it to my FlatList.

The problem now is that when I execute the code, the this.setState({ mechanicsList: mechanicsTemp }); returns an error.

Error

[Unhandled promise rejection: TypeError: this.setState is not a function. 

(In 'this.setState({]
* src\screens\FindMechanics.js:28:30 in <unknown>
- node_modules\promise\setimmediate\core.js:37:14 in tryCallOne
- node_modules\promise\setimmediate\core.js:123:25 in <unknown>
- ... 8 more stack frames from framework internals

Full Code

import React, { Component } from 'react';
import { View, Text, SafeAreaView, TouchableOpacity, ScrollView, StyleSheet } from "react-native";
import { Card } from 'react-native-elements'
import firebase from "firebase/app";

export default class FindMechanics extends Component {
    constructor(props) {
        super(props);
        this.state = {
            mechanicsList: [],
            isDataLoaded: false
        }
    }

    componentDidMount() {
        var query = firebase.database().ref("MechanicList").orderByKey();
        query.once("value")
            .then(function (snapshot) {
                let mechanicsTemp = [];
                snapshot.forEach(function (childSnapshot) {
                    // key will be the auth ID for each user
                    var key = childSnapshot.key;
                    var mechanicName = snapshot.child(key + '/name').val();
                    mechanicsTemp.push({ _name: mechanicName, _key: key });
                });           
                mechanicsList = mechanicsTemp;            
                () => this.setState({ mechanicsList: mechanicsTemp }); // This does not execute it seems - main problem I believe
                //this.setState({ mechanicsList: mechanicsTemp }); - This return a warning 'this.setState is not a function'
                console.log(mechanicsList); //Prints data as expected
                mechanicsTemp.forEach((mechanic) => {
                   console.log( mechanic._name); //Prints data as expected
                });
            });
    }

    render() {
        //The Card element is empty - nothing shows. 
        console.log(this.state.mechanicsList) //This return Array [] which indicates it is empty
        return (
            <SafeAreaView style={styles.container}>
                <ScrollView horizontal={true}>
                    <TouchableOpacity>
                        <Card style={styles.card}>
                            {
                                this.state.mechanicsList.map((u, i) => {
                                    return (
                                        <View key={i}>
                                            <Text>{u._key}</Text>
                                            <Text>{u._name}</Text>
                                        </View>
                                    );
                                })
                            }
                        </Card>
                    </TouchableOpacity>
                </ScrollView>
            </SafeAreaView>
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: '#FFF'
    },
    paragraph: {
        margin: 24,
        fontSize: 18,
        textAlign: 'center',
    },
    card: {
        flex: 1,
        width: '80%',
    },
});

Console

Finished building JavaScript bundle in 384ms.
Running application on Android SDK built for x86.
Array []

2 Answers 2

3

1st thing, you have mechanics object in state so you need to access it like

console.log(this.state.mechanics)

2nd thing is that you are not updating state variable when you are having data, it should be like following

let mechanicsTemp = [];
snapshot.forEach(function (childSnapshot) {
    // key will be the auth ID for each user
    var key = childSnapshot.key;
    var mechanicName = snapshot.child(key + '/name').val();
    mechanicsTemp.push({_name: mechanicName, _key: key});
});

this.setState({ mechanics:mechanicsTemp })
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the reply. When I try the above, I now get Array [] printed in my console rather than undefined. I updated the code above in the description.
you forgot to change variable name while pushing data, it should be mechanicsTemp
Ah yes, my mistake - sorry! Weirdly even after that change I get the same result: Array []. I cannot see anything else I may have forgot..I updated the code above again.
I believe debugging it can help you more. Have some logs when you have data, try to log mechanicsTemp also.
No worries - I'll give it a shot and hopefully get it sorted. Thanks for the help.
|
1

I dunno if you still need help with this or not but I just used your code and I solved this.setState problem with binding. You can either use arrow function or bind your function:

.then(function (snapshot) {
// ..
}.bind(this));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.