Mohd Saif khan
Mohd Saif khan

Reputation: 65

React Native Component Exception: undefined is not an object (evaluating'_this')

Iam working on face recognition app using react native 0.63. I am runing my project using react-native run-android. I get Component Exception undefined is not an object(evaluating '_this'). I am new to react native and I do not understand the meaning of this error. I am following the tutorial for this app but the tutorial is very old and thats why I am unable to update the code to latest version of react native. Here is the link of tutorial Face Recognition using react native. Please take a look and resolve my issue.

import React from 'react';

import {StyleSheet,Text,View,Image} from 'react-native';
 
import NativeModules, { ImagePickerManager } from 'react-native';
 
import Button from './Button';
 
import RNFetchBlob from 'react-native-fetch-blob';
 
import _ from 'lodash';
 
const Detector = props => {

this.state = {
    photo_style: {
        position: 'relative',
        width: 480,
        height: 480
    },
    has_photo: false,
    photo: null,
    face_data: null
};

return (
  <View style={styles.container}>
     
    <Image
        style={this.state.photo_style}
        source={this.state.photo}
        resizeMode={"contain"}
    >
        { this._renderFaceBoxes.call(this) }
    </Image>
 
    <Button
        title="Pick Photo"
        onPress={()=>{this._pickImage.bind(this)}}
        button_styles={styles.button}
        button_text_styles={styles.button_text} />

    { this._renderDetectFacesButton.call(this) }

  </View>
);


}

  const _pickImage = () => {
 
this.setState({
    face_data: null
});

ImagePickerManager.showImagePicker(this.props.imagePickerOptions, (response) => {
     
  if(response.error){
    alert('Error getting the image. Please try again.');
  }else{
     
    let source = {uri: response.uri};

    this.setState({
      photo_style: {
        position: 'relative',
        width: response.width,
        height: response.height
      },
      has_photo: true,
      photo: source,
      photo_data: response.data
    });
     
  }
});



}
 
  const _renderDetectFacesButton = () => {
    if(this.state.has_photo){
        return  (
            <Button
                title="Detect Faces"
                onPress={()=>{this._detectFaces.bind(this)}}
                button_styles={styles.button}
                button_text_styles={styles.button_text} />
        );
    }
  }
 
  const _detectFaces = () => {
RNFetchBlob.fetch('POST', 'https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=true&returnFaceAttributes=age,gender', {
    'Accept': 'application/json',
    'Content-Type': 'application/octet-stream',
    'Ocp-Apim-Subscription-Key': this.props.apiKey
}, this.state.photo_data)
.then((res) => {
    return res.json();      
})
.then((json) => {
     
    if(json.length){
        this.setState({
            face_data: json
        });
    }else{
        alert("Sorry, I can't see any faces in there.");
    }
     
    return json;
})
.catch (function (error) {
    console.log(error);
    alert('Sorry, the request failed. Please try again.' + JSON.stringify(error));
});
 



}
 
  const _renderFaceBoxes = () => {
if(this.state.face_data){

    let views = _.map(this.state.face_data, (x) => {
         
        let box = {
            position: 'absolute',
            top: x.faceRectangle.top,
            left: x.faceRectangle.left
        };

        let style = { 
            width: x.faceRectangle.width,
            height: x.faceRectangle.height,
            borderWidth: 2,
            borderColor: '#fff',
        };
         
        let attr = {
            color: '#fff',
        };

        return (
            <View key={x.faceId} style={box}>
                <View style={style}></View>
                <Text style={attr}>{x.faceAttributes.gender}, {x.faceAttributes.age} y/o</Text>
            </View>
        );
    });

    return <View>{views}</View>
}



 }
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    alignSelf: 'center',
    backgroundColor: '#ccc'
  },
  button: {
    margin: 10,
    padding: 15,
    backgroundColor: '#529ecc'
  },
  button_text: {
    color: '#FFF',
    fontSize: 20
  }
});
 
export default Detector 

enter image description here

Upvotes: 0

Views: 1058

Answers (1)

Thomas
Thomas

Reputation: 8003

Your component is defined as const Detector = props => { making it a function component. Function components don't have a "this" and don't have methods like setState or componentDidMount. There are two ways you can solve your problem.

  1. Either you make a component that inherits from React.Component. See the docs. When you do this, this will be available, as well as other component methods like this.setState.
  2. Or you use hooks like useState to manage the state inside your components. docs

Which one you choose depends on preference, although hooks is the "newer" way of doing things.

Upvotes: 1

Related Questions