TaskManager: undefined is not an object

Hey guys,

I’m trying to get a simple example of a geofence working using TaskManager. I’m getting an
undefined is not an object (evaluating _expo.TaskManager.defineTask). Here’s what I have (App.js code is taken from someone else’s previous post, although I’ve tried even more minimal versions of it but get the same issue).

App.js

 import React, {Component} from 'react';
import { AppRegistry, Text, View, StyleSheet, FlatList, Image } from 'react-native';
import { Constants, MapView, Location, TaskManager, Permissions } from 'expo';

TaskManager.defineTask('geoTask', ({ data: { eventType, region }, error }) => {
  if (error) {
    console.log("geoTaskError", {error});
    return;
  }
  if (eventType === Location.GeofencingEventType.Enter) {
    console.log("geoTaskEnter", { eventType, region });
  } 
  else if (eventType === Location.GeofencingEventType.Exit) {
    console.log("geoTaskExit", { eventType, region });
  }
});


export default class App extends Component {
  constructor() {
    super ()
    this.state = {
      dataSource: []
    }
  }

  state = {
    mapRegion: null,
    hasLocationPermissions: false,
    locationResult: null
  };

  _handleMapRegionChange = mapRegion => {
    console.log(mapRegion);
    this.setState({ mapRegion });
  };

  _getLocationAsync = async () => {
   let { status } = await Permissions.askAsync(Permissions.LOCATION);
   if (status !== 'granted') {
     this.setState({
       locationResult: 'Permission to access location was denied',
     });
   } else {
     this.setState({ hasLocationPermissions: true });
   }

  let location = await Location.getCurrentPositionAsync({});
    this.setState({ locationLat: (location.coords.latitude) });
    this.setState({ locationLon: (location.coords.longitude) });
    this.setState({ locationResult: JSON.stringify(location) });

   // Center the map on the location we just fetched.
  this.setState({mapRegion: { latitude: location.coords.latitude, longitude: location.coords.longitude, latitudeDelta: 0.0922, longitudeDelta: 0.0421 }});
  };

  _startGeofencingAsync = async (geoTask, regions) => {
  this.setState ({ regions: {radius: 4000}})
  };

  renderItem = ({item}) => {
    return (
    <View>
      <View>
        <Text>CODE: {item.code}
        <Text> AIRPORT NAME: {item.name}
        <Text> LAT: {item.lat}
        <Text> LONG: {item.lon} 
        </Text>
        </Text>
        </Text>
        </Text>
      </View>
    </View>
  )}

  componentDidMount() {
    this._getLocationAsync();
    //const url = 'https://www.json-generator.com/api/json/get/ccLAsEcOSq?indent=1'
    const url = 'https://gist.githubusercontent.com/tdreyno/4278655/raw/7b0762c09b519f40397e4c3e100b097d861f5588/airports.json'
    fetch(url)
    .then((repsonse) => repsonse.json())
    .then((responseJson) => {
      this.setState({
        dataSource: responseJson
      })
    })
    .catch((error) => {
        console.log(error)    
    });

    let onPress = async () => {
    await Location.startLocationUpdatesAsync('geoTask', {
      accuracy: Location.Accuracy.Balanced,
    });
  };
  }

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

        <Text>Latitude: {this.state.locationLat}</Text>
        <Text>Longitude: {this.state.locationLon}</Text>
        <Text>Location: {this.state.locationResult}</Text>

      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={this.renderItem}
          />
      </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

package.json

{
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "web": "expo start --web",
    "start": "react-native start",
    "test": "jest"
  },
  "dependencies": {
    "expo": "^34.0.1",
    "react": "16.8.3",
    "react-dom": "^16.8.6",
    "react-native-web": "^0.11.4",
    "react-native": "0.59.8",
    "react-native-gesture-handler": "~1.3.0",
    "react-native-reanimated": "~1.1.0",
    "react-native-unimodules": "~0.5.2"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "babel-jest": "24.1.0",
    "jest": "24.1.0",
    "metro-react-native-babel-preset": "0.54.0",
    "react-test-renderer": "16.6.3"
  },
  "jest": {
    "preset": "react-native"
  },
  "private": true
}

Help would really be appreciated! I’m on the latest SDK (34) as seen in package.json

Hey @pkonduri,

The way you import modules has changed with SDK34. You’ll now need to run expo install for each module you use and you’ll import it from it’s respective package rather than from the Expo package. So for TaskManager, you’ll run expo install expo-task-manger and import it with import * as TaskManger from 'expo-task-manager'. (See: https://docs.expo.io/versions/v34.0.0/sdk/task-manager/#installation)

You’ll want to check each module’s documentation page for the proper way to install and import each as there are still some that live in the Expo package, but most have been isolated to their own package now.

Cheers,
Adam

Appreciate the help, thanks!

1 Like

Happy to be of service!

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.