user2028
user2028

Reputation: 183

undefined is not an object(evaluating '_this2.props.navigation)

I am new to react native and trying to learn it by myself. i have implemented Navigation drawer and have made some of screens .in my demo i am having listview and i am just trying to navigate user to the selected item detail page , but i m getting above mentioned error.

Here is index.android.js file :-

import React, { Component } from 'react';
import {
  AppRegistry,
} from 'react-native';
import Main from './src/Main'
import { DrawerNavigator } from 'react-navigation';
import { TabNavigator } from 'react-navigation';
import LoginScreen from './src/LoginScreen';
import { StackNavigator } from 'react-navigation';
import movielisting from './src/movielisting';
class reactNavigationSample extends Component {
  render(){
    const { navigation } = this.props;
    return (
  <MyComponent navigation={navigation}/>
    );
  }
}
const DrawerApp = DrawerNavigator({
    movielisting: {screen: movielisting},
      LoginScreen:{ screen: Main},

});
AppRegistry.registerComponent('reactNavigationSample', () => DrawerApp);

Listing page :-

import React, { Component } from 'react';
import { StatusBar } from 'react-native'
import { StackNavigator } from 'react-navigation';
import { NavigationActions } from 'react-navigation';
import { Actions, ActionConst } from 'react-native-router-flux';

import home  from './images/home.png';
import ActionBar from './ActionBar';
import ProgressBar from './ProgressBar';
const { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');
import {
  StyleSheet,
  Text,
  Image,
  View,
  AsyncStorage,
  TouchableOpacity,TouchableHighlight,Dimensions,ListView
} from 'react-native';
const uri = 'http://csswrap.com/wp-content/uploads/2015/03/showmenu.png';


export default class movielisting extends Component {

 constructor(props) {
     super(props);
     var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
     this.state = {
       moviesData: ds.cloneWithRows([]),
     };
   }
   componentDidMount() {
       this.fetchMoviesData();
     }
    renderRow(rowData){
    AsyncStorage.setItem('moviesData', JSON.stringify(rowData));
        return (
          <View style={styles.thumb} >
          <TouchableOpacity onPress={() => this.props.navigation.navigate('MovieDeatilScreen')}>
            <Image
              source={{uri:'https://image.tmdb.org/t/p/w500_and_h281_bestv2/'+rowData.poster_path}}
              resizeMode="cover"
              style={styles.img} />
              <Text style={styles.txt}>{rowData.title} (Rating: {Math.round( rowData.vote_average * 10 ) / 10})</Text>
          </TouchableOpacity>
          </View>

        );
      }
      fetchMoviesData() {
          var url = 'http://api.themoviedb.org/3/movie/now_playing?api_key=17e62b78e65bd6b35f038505c1eec409';
          fetch(url)
            .then( response => response.json() )
            .then( jsonData => {
              this.setState({
                moviesData: this.state.moviesData.cloneWithRows(jsonData.results),
              });
            })
          .catch( error => console.log('Error fetching: ' + error) );
        }
  render() {
        return (
                <View style={styles.container}>
                <View style={styles.navBar}>
                 <TouchableOpacity onPress={() => this.props.navigation.navigate('DrawerOpen')} style={styles.action} >
                                                             <Image style={styles.avatar} source={{uri}} />
                                                                  </TouchableOpacity>

                          <Text style={styles.navBarHeader}>Movie List Screen</Text>
                        </View>
                    <ListView
                            dataSource={this.state.moviesData}
                            renderRow={this.renderRow}
                            enableEmptySections={true}
                             style={styles.ListViewcontainer}
                          />
                 <View style={styles.footer}>
                               <ActionBar />
                                </View>
                    </View>
        );
    }
    renderLoader(){
            return (
                this.state.showLoader?<View><Spinner color='red' /></View>:null
            )
        }
    hideLoader(){
            setTimeout(() => {
                this.setState({showLoader:false})
            }, 1);
        }
}
const styles = StyleSheet.create({
  container: {
  position:'relative',
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
          footer: {
            position: 'absolute',
            flex:0.1,
            left: 0,
            right: 0,
            bottom: -12,
            flexDirection:'row',
            height:70,
            alignItems:'center',
          },
                navBar: {
                 position: 'absolute',
                 flexDirection: 'row',
                 top:0,
                 right:0,
                 left:0,
                   paddingTop:15,
                    height: 64,
                    backgroundColor: '#1EAAF1'
                  },
                      navBarHeader: {
                      flex: 1,
                      left:30,
                       paddingTop:5,
                      top:2,
                        color: '#FFFFFF',
                        fontWeight: 'bold',
                        textAlign: 'left',
                      },avatar: {
                      left:10,
                                bottom:3,
                               width: 35,
                               height: 35,
                              },action: {
                                        flex: 0.4,
                                    },thumb: {
                                          backgroundColor: '#ffffff',
                                          marginBottom: 5,
                                          elevation: 1
                                        },
                                        img: {
                                          height: 300
                                        },
                                        txt: {
                                          margin: 10,
                                          fontSize: 16,
                                          textAlign: 'left'
                                        },ListViewcontainer:{
                                         marginTop:110,
                                          bottom: 50,
                                        }
});
 movielisting.navigationOptions = {
  drawer: {
      icon: () => (
        <Image
          source={home}
          style={[styles.tabIcon, {tintColor: 'black'}]}
        />
  )}

};

MovieDetail screen page :-

import React, { Component, PropTypes } from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image,
  TouchableOpacity,
  TextInput,
  AsyncStorage,
  Icon
} from 'react-native';
import ActionBar from './ActionBar';
import { StackNavigator } from 'react-navigation';
import { NavigationActions } from 'react-navigation';
import Dimensions from 'Dimensions';
import { Actions, ActionConst } from 'react-native-router-flux';
const uri = 'http://csswrap.com/wp-content/uploads/2015/03/showmenu.png';
export default class MovieDeatilScreen extends Component {

constructor(props){
super(props);
 this.state = {
moviesData:''
        };
}

componentDidMount() {
        AsyncStorage.getItem("moviesData").then((value) => {
            this.setState({"moviesData": JSON.parse(value)});
//            this.Loaddata();
        }).done();

    }


//   Loaddata() {
//  for(let i = 0; i < this.state.moviesData.length; i++){
//
//  this.setState({'username' : this.state.SignedUpuser[i].name});
//
//    }
//    }

render() {
    return (
    <View style={styles.container}>
    <View style={styles.navBar}>
                     <TouchableOpacity onPress={() => this.props.navigation.navigate('DrawerOpen')} style={styles.action} >
                                                                 <Image style={styles.avatar} source={{uri}} />
                                                                      </TouchableOpacity>

                              <Text style={styles.navBarHeader}>Movie Deatil Screen</Text>
                            </View>
 <View style={styles.thumb}>
            <Image
              source={{uri:'https://image.tmdb.org/t/p/w500_and_h281_bestv2/'+this.state.moviesData.poster_path}}
              resizeMode="cover"
              style={styles.img} />
              <Text style={styles.txt}>{this.state.moviesData.title} (Rating: {Math.round( this.state.moviesData.vote_average * 10 ) / 10})</Text>
          </View>
          <View style={styles.footer}>
                                         <ActionBar />
                                          </View>
          </View>
    );
}
}
const DEVICE_WIDTH = Dimensions.get('window').width;
const DEVICE_HEIGHT = Dimensions.get('window').height;
const styles = StyleSheet.create({
container: {
  position:'relative',
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
          footer: {
            position: 'absolute',
            flex:0.1,
            left: 0,
            right: 0,
            bottom: -12,
            flexDirection:'row',
            height:70,
            alignItems:'center',
          },
                navBar: {
                 position: 'absolute',
                 flexDirection: 'row',
                 top:0,
                 right:0,
                 left:0,
                   paddingTop:15,
                    height: 64,
                    backgroundColor: '#1EAAF1'
                  },
                      navBarHeader: {
                      flex: 1,
                      left:30,
                       paddingTop:5,
                      top:2,
                        color: '#FFFFFF',
                        fontWeight: 'bold',
                        textAlign: 'left',
                      },avatar: {
                      left:10,
                                bottom:3,
                               width: 35,
                               height: 35,
                              },action: {
                                        flex: 0.4,
                                    },thumb: {
                                          backgroundColor: '#ffffff',
                                          marginBottom: 5,
                                          elevation: 1
                                        },
                                        img: {
                                          height: 300
                                        },
                                        txt: {
                                          margin: 10,
                                          fontSize: 16,
                                          textAlign: 'left'
                                        },ListViewcontainer:{
                                         marginTop:110,
                                          bottom: 50,
                                        }
});
MovieDeatilScreen.navigationOptions = {
  drawer: {
      icon: () => (
        <Image
          source={home}
          style={[styles.tabIcon, {tintColor: 'black'}]}
        />
  )}

};

Can any one help me how to navigate to detail screen on list item click.Does i need to implement navigator separately for this functionality and should be using this.props.navigation.push(tilename and component name) ?

Thanks!!!

Upvotes: 0

Views: 1175

Answers (1)

Bamse
Bamse

Reputation: 493

I think i have some idea, the problem you are getting is related to the function binding.

The renderRow function does not have access to this which means that you have to bind it, you can do that in your constructor or just make it an arrow function.

Method 1: bind it in the constructor like this:

this.renderRow = this.renderRow.bind(this)

Method 2: implicit binding in declaration:

renderRow = (rowData) => { ... }

Hope this will work.

Upvotes: 2

Related Questions