Search code examples
reactjsreact-google-mapsrecompose

Top level function - TypeError: Object(...) is not a function compose


In my project I am defining a top level Component using recompose/react-google-maps as follows:

const LocationPicker = compose(
    withProps({
        googleMapURL: "https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,places&key=AIzaSyDnKwHUG_EJXN5EEW6hTftZHYo8E8QTTXY",
        loadingElement: <div style={{ height: `100%` }} />,
        containerElement: <div style={{ height: `400px` }} />,
        mapElement: <div style={{ height: `100%` }} />,
    }),
    withScriptjs,
    withGoogleMap,
    withState('places', '', ''),
    withHandlers(() => {
        refs = {
            map: undefined,
        }

        return {
            onMapMounted: () => ref => {
                refs.map = ref
                service = new google.maps.places.PlacesService(refs.map.context.__SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED);
            },
        }
    }),
)((props) => {
    return (
        <GoogleMap
            ref={props.onMapMounted}
            defaultZoom={13}
            defaultCenter={{ lat: 42.3570637, lng: -71.06257679999999 }}
        >
            {props.marker &&
                <Marker position={{ lat: props.marker.lat, lng: props.marker.lng }} draggable={true} />
            }
        </GoogleMap>
    )
})

This iss a Component defined outside the scope of class. I am getting the following error: TypeError: Object(...) is not a function enter image description here Why can't I define the component like this?


Solution

  • To start I would break this up into a stateless functional component and then enhance the component with Recompose.

    const LocationPickerView = props => (
      <GoogleMap
        ref={props.onMapMounted}
        defaultZoom={13}
        defaultCenter={{ lat: 42.3570637, lng: -71.06257679999999 }}
      >
        {props.marker && (
          <Marker position={{ lat: props.marker.lat, lng: props.marker.lng }} draggable />
        )}
      </GoogleMap>
    );
    
    const LocationPicker = compose(
      withProps({
        googleMapURL:
          'https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,places&key=AIzaSyDnKwHUG_EJXN5EEW6hTftZHYo8E8QTTXY',
        loadingElement: <div style={{ height: '100%' }} />,
        containerElement: <div style={{ height: '400px' }} />,
        mapElement: <div style={{ height: '100%' }} />
      }),
      withScriptjs,
      withGoogleMap,
      withState('places', '', ''),
      withHandlers(() => {
        refs = {
          map: undefined
        };
    
        return {
          onMapMounted: () => ref => {
            refs.map = ref;
            service = new google.maps.places.PlacesService(
              refs.map.context.__SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
            );
          }
        };
      })
    )(LocationPickerView);
    

    I think that will solve your TypeError. If not, try commenting out the ref and withHandler sections. You may have a separate issue there.