Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

Importing MarkerClusterGroup results in TypeError #71

Open
reggie3 opened this issue Jul 6, 2018 · 38 comments
Open

Importing MarkerClusterGroup results in TypeError #71

reggie3 opened this issue Jul 6, 2018 · 38 comments

Comments

@reggie3
Copy link

reggie3 commented Jul 6, 2018

I am receiving the following error when trying to use this package.

TypeError: Super expression must either be null or a function, not object

The entire error is shown here:
image

The error is associated with these lines of code in the react-leaflet-markcluster.js file (line numbers differ from what is shown in the error because of Chrome debugger formatting)
image

I am trying to use the package in a Gatsby project, but I don't think that is causing the error. I am successfully able to import and use the react-leaflet project.

Version Info:

"react-leaflet": "^2.0.0",
"react-leaflet-markercluster": "^1.1.8",
"leaflet": "^1.3.1",
"leaflet.markercluster": "^1.3.0",
"gatsby": "^1.9.273",

Related Import Statements

import {
  Map,
  TileLayer,
  Marker,
  Popup,
} from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import MarkerClusterGroup from 'react-leaflet-markercluster/dist/react-leaflet-markercluster';
import 'react-leaflet-markercluster/dist/styles.min.css'; 
@oserban
Copy link

oserban commented Jul 6, 2018

I have the same issue with:

"leaflet": "^1.3.1",
"leaflet.markercluster": "^1.3.0",
"react-leaflet": "^2.0.0-rc.3",
"react-leaflet-markercluster": "^1.1.8",

Is there a recommended version for these libraries?

@yuzhva
Copy link
Owner

yuzhva commented Jul 6, 2018

This plugin does not support react-leaflet v2.

@ThiefMaster
Copy link

Any plans to update it to include v2 support?

@yuzhva
Copy link
Owner

yuzhva commented Jul 6, 2018

@ThiefMaster yep, I will try to deliver it during the next week.
The trick is that react-leaflet was as the candidate release till that day.

So since today, I need to update this lib.
I will update package.json dependency to solve that issue in v1.1.9.

And since v2.0 there will be support of react-leaflet ^2.0 latest React context from 16.3

@webcarrot
Copy link

Temporary version:

import { MapLayer, withLeaflet } from "react-leaflet";
import L from "leaflet";

require("leaflet.markercluster");

class MarkerClusterGroup extends MapLayer {

  createLeafletElement(props) {
    const el = new L.markerClusterGroup(props);
    this.contextValue = {
      ...props.leaflet,
      layerContainer: el
    };
    return el;
  }

}

export default withLeaflet(MarkerClusterGroup);

@yuzhva
Copy link
Owner

yuzhva commented Jul 8, 2018

@webcarrot Many thanks for your contribution!

@reggie3 @oserban @ThiefMaster

Currently, the latest version with support of react-leaflet v2.0 and React 16.3 context API available as candidate release:

yarn add react-leaflet-markercluster@next # yarn
npm install react-leaflet-markercluster@next # npm

After the README and demo-app will be updated will publish it as release package.

P.S: it's stable and I think there would no be any changes in final release, so enjoy it (=

@webcarrot
Copy link

Hi.

  1. In react-leaflet-markercluster@next version markers pop-ups do not display content - probably they need map from props.leaflet to be set/provided in MarkerClusterGroup instance contextValue.
  2. In my temporary version events handlers are "automagically" used by L.markerClusterGroup plugin so probably there is no need to reduce/filter/split props in createLeafletElement to handle events manually.
  3. This temporary version simply drop support for deprecated API (markers, options etc.).

Sorry for my English.

@yuzhva
Copy link
Owner

yuzhva commented Jul 9, 2018

@webcarrot

In react-leaflet-markercluster@next version markers pop-ups do not display content - probably they need map from props.leaflet to be set/provided in MarkerClusterGroup instance contextValue.

Yep, you are right. Already fixed it in 2.0.0-rc2 so it's published.

events handlers are "automagically"
Just it's semantically inconveniently to use it. When you are writing some event handler on a cluster like:

<MarkerClusterGroup onClusterClick={} onCLusterMouseOver={} />

The repeating word Cluster seems superfluous

<MarkerClusterGroup onClick={} onMouseOver={} />

Gives a cleaner way of using props for event handlers.

@oserban
Copy link

oserban commented Jul 12, 2018

The 2.0.0-rc3 version works flawlessly with my use case. Thanks.

@webdobe
Copy link

webdobe commented Jul 18, 2018

I'm getting similar behavior and cannot get past it for the life of me.

"leaflet": "^1.3.2",
"leaflet.markercluster": "^1.3.0",
"react-leaflet": "^2.0.0",
"react-leaflet-markercluster": "^2.0.0-rc3",

I hit the error:

leaflet.markercluster-src.js?d09f:17 Uncaught ReferenceError: L is not defined
    at eval (leaflet.markercluster-src.js?d09f:17)
    at L.MarkerClusterGroup.L.FeatureGroup.extend.options.maxClusterRadius (leaflet.markercluster-src.js?d09f:8)
    at eval (leaflet.markercluster-src.js?d09f:11)
    at Object.<anonymous> (bundle.js:11987)
    at __webpack_require__ (bundle.js:20)
    at eval (react-leaflet-markercluster.min.js?a99b:1)
    at Object.<anonymous> (bundle.js:11976)
    at __webpack_require__ (bundle.js:20)
    at eval (MarkersLayer.js?ba8d:4)
    at Object.<anonymous> (bundle.js:11964)
(anonymous) @ leaflet.markercluster-src.js?d09f:17
L.MarkerClusterGroup.L.FeatureGroup.extend.options.maxClusterRadius @ leaflet.markercluster-src.js?d09f:8

If I add leaflet.js directly to the index.html
Then I get the same error that started this thread.

react-leaflet-markercluster.min.js?a99b:1 Uncaught TypeError: Cannot read property 'markerClusterGroup' of undefined
    at t.value (react-leaflet-markercluster.min.js?a99b:1)
    at t.MapLayer (MapLayer.js?a679:24)
    at new t (react-leaflet-markercluster.min.js?a99b:1)
    at constructClassInstance (react-dom.development.js?cada:11447)
    at updateClassComponent (react-dom.development.js?cada:13144)
    at beginWork (react-dom.development.js?cada:13824)
    at performUnitOfWork (react-dom.development.js?cada:15863)
    at workLoop (react-dom.development.js?cada:15902)
    at HTMLUnknownElement.callCallback (react-dom.development.js?cada:100)
    at Object.invokeGuardedCallbackDev (react-dom.development.js?cada:138)

I'v tried @webcarrot's recommendation and still no dice. I have tried playing with 1000 different dependency combinations with no success clearing npm cache etc.

Kind at a loss right now. Any help is much appreciated.

@yuzhva
Copy link
Owner

yuzhva commented Jul 18, 2018

@webdobe

You need to install all peerDependencies:

yarn add leaflet.markercluster leaflet react-leaflet prop-types

Then install next release of that plugin:

yarn add react-leaflet-markercluster@next

Previously try to remove node_modules and clean all lock files if you have them to reset prev. versions.

@webdobe
Copy link

webdobe commented Jul 19, 2018

@yuzhva

Thank you soo much! I think I was missing prop-types when I was doing that exact same thing. I also ended up removing react and react-dom from my package.json and added that to the above just for good measure as it was complaining about my version of those as well.

@jwmann
Copy link

jwmann commented Jan 16, 2019

@yuzhva

I'm still getting the above error and I'm using 2.0.0-rc3

package.json

{
    "leaflet": "^1.4.0",
    "leaflet.markercluster": "^1.4.1",
    "react-leaflet": "^2.2.0",
    "react-leaflet-markercluster": "^2.0.0-rc3",
}

component

import { Map, CircleMarker, Tooltip, TileLayer } from 'react-leaflet';
import MarkerClusterGroup from 'react-leaflet-markercluster';

component.less

@import '~leaflet/dist/leaflet.css?url=false';
@import '~leaflet.markercluster/dist/MarkerCluster.css';
@import '~leaflet.markercluster/dist/MarkerCluster.Default.css';
@import '~react-leaflet-markercluster/dist/styles.min.css';

@jwmann
Copy link

jwmann commented Jan 16, 2019

Oddly, if I specifically use the dist version like the OP's example

import MarkerClusterGroup from 'react-leaflet-markercluster/dist/react-leaflet-markercluster';

It seems to work. (I had to set a maxZoom for the Map but that was a minor issue)

@adambisek
Copy link

For me, with react-leaflet 2 worked solution from #issuecomment-403071677
(WITHOUT USING THIS PACKAGE react-leaflet-markercluster)

import { MapLayer, withLeaflet } from '../src'
import L from "leaflet";

require("leaflet.markercluster");

class MarkerClusterGroup extends MapLayer {

  createLeafletElement(props) {
    const el = new L.markerClusterGroup(props);
    this.contextValue = {
      ...props.leaflet,
      layerContainer: el
    };
    return el;
  }

}

export default withLeaflet(MarkerClusterGroup);

Dependencies version:

    "react-leaflet": "2.2.1",
    "leaflet": "^1.4.0",
    "leaflet.markercluster": "^1.4.1",

@Bigood
Copy link

Bigood commented Jun 25, 2019

In case someone using Next.js stumbles upon here and use react-leaflet-universal (as I did), I confirm the rc3 works properly! You have to use next's dynamic() to import it client-side though.

import { Marker } from 'react-leaflet-universal'
//https://github.com/zeit/next.js/wiki/FAQ
//https://stackoverflow.com/questions/52939439/dynamic-import-node-module-with-next-js
import dynamic from 'next/dynamic'
const MarkerClusterGroup = dynamic(import('react-leaflet-markercluster'), {ssr: false})

...

<Map 
  //Custom component wrapping react-leaflet's Map, also loaded with dynamic()
  //Don't forget to add the maxZoom, or it'll die
  maxZoom={10} 
  >
    <MarkerClusterGroup>
        <Marker … />
        <Marker … />
        <Marker … />
    </MarkerClusterGroup>
</Map>

Deps :

    "leaflet": "^1.5.1",
    "leaflet.markercluster": "^1.4.1",
    "react-leaflet": "^2.3.0",
    "react-leaflet-markercluster": "^2.0.0-rc3",
    "react-leaflet-universal": "^2.1.0",

@stereobooster
Copy link

"leaflet": "1.5.1",
"leaflet.markercluster": "1.4.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-leaflet": "2.3.0",
"react-leaflet-markercluster": "2.0.0-rc3",

I get the following error

The error: _leaflet2.default.markerClusterGroup is not a constructor

@stereobooster
Copy link

stereobooster commented Oct 11, 2019

import { MapLayer, withLeaflet } from "react-leaflet";
import "leaflet.markercluster";
import { MarkerClusterGroupProps } from "react-leaflet-markercluster";

// https://github.com/YUzhva/react-leaflet-markercluster/issues/71#issuecomment-466393028
class MarkerClusterGroup extends MapLayer {
  createLeafletElement(props: MarkerClusterGroupProps) {
    // @ts-ignore
    const el = new L.markerClusterGroup(props);
    this.contextValue = {
      ...props.leaflet,
      layerContainer: el,
    };
    return el;
  }
}

export default withLeaflet(MarkerClusterGroup);

gives this error

leaflet-src.js:1282 Uncaught TypeError: Cannot read property 'lat' of undefined
    at LatLngBounds.intersects (leaflet-src.js:1282)
    at e._recursively (leaflet.markercluster-src.js:1780)
    at e._recursivelyRemoveChildrenFromMap (leaflet.markercluster-src.js:1726)
    at e._moveEnd (leaflet.markercluster-src.js:931)
    at NewClass.fire (leaflet-src.js:593)
    at NewClass.panBy (leaflet-src.js:3313)
    at NewClass._tryAnimatedPan (leaflet-src.js:4592)
    at NewClass.setView (leaflet-src.js:3191)
    at Map.updateLeafletElement (Map.js:129)
    at Map.componentDidUpdate (Map.js:245)

UPD it seems I found why, because somehow leaflet resolves to different packages (hello webpack). As the result execution gets to this point:

function toLatLngBounds(a, b) {
	if (a instanceof LatLngBounds) {
		return a;
	}
	return new LatLngBounds(a, b);
}

where a is LatLngBounds (it has all the same methods), but it is not instance of LatLngBounds (it identifies itself as B).

Screenshot 2019-10-14 at 11 44 24

@saadsaifse
Copy link

@stereobooster I am stumbling upon the same problem, did you find any solution for this with Typescript?

@stereobooster
Copy link

@saadsaifse end up using mapbox (with open source tiles)

@saadsaifse
Copy link

@stereobooster that's for the base layers I presume? How did you manage to get marker clustering without Leaflet?

@stereobooster
Copy link

@saadsaifse first result from googling "mapbox cluster" https://docs.mapbox.com/mapbox-gl-js/example/cluster/

@emilhe
Copy link

emilhe commented Apr 16, 2020

I was also getting type errors, e.g. "TypeError: Cannot read property 'removeLayer' of undefined". However, using the code posted by @adambisek plus a css import, it seems to work. Here is the (slightly) modified code,

import { MapLayer, withLeaflet } from 'react-leaflet';
import L from "leaflet";

require("leaflet.markercluster");
require('react-leaflet-markercluster/dist/styles.min.css');

class MarkerClusterGroup extends MapLayer {

  createLeafletElement(props) {
    const el = new L.markerClusterGroup(props);
    this.contextValue = {
      ...props.leaflet,
      layerContainer: el
    };
    return el;
  }

}

export default withLeaflet(MarkerClusterGroup);

@umitduran
Copy link

@yuzhva i have same problems with below versions. I read all comments and tried a lot of things but i couldn't solve this problem. What should i try ?

  • "react-leaflet": "^2.2.1",
  • "leaflet.markercluster": "^1.4.1",
  • "leaflet": "1.4.0",
  • "react": "^16.8.1",
  • "react-dom": "^16.8.1",

Screen Shot 2020-08-31 at 09 59 40
Screen Shot 2020-08-31 at 10 00 16

@yuzhva
Copy link
Owner

yuzhva commented Aug 31, 2020

You are not supported to use v1.4.1 of this library with react-leaflet v2 and react ^16.

Try to remove and then add leaflet.markercluster again:

yarn remove leaflet.markercluster
yarn add leaflet.markercluster

leaflet.markercluster should be of v2.0.0

@umitduran
Copy link

You are not supported to use v1.4.1 of this library with react-leaflet v2 and react ^16.

Try to remove and then add leaflet.markercluster again:

yarn remove leaflet.markercluster
yarn add leaflet.markercluster

leaflet.markercluster should be of v2.0.0

@yuzhva are you sure leaflet.markercluster is possible with v2.0.0 because leaflet.markercluster latest version is 1.4.1 ?

@yuzhva
Copy link
Owner

yuzhva commented Sep 1, 2020

oh yeah, I mixed up leaflet.markercluster with this react-leaflet-markercluster package.

@umitduran what version of react-leaflet-markercluster are you using?

@umitduran
Copy link

@yuzhva my versions are below

  • "leaflet": "1.4.0",
  • "leaflet-draw": "^0.4.12",
  • "react": "^16.8.1",
  • "react-leaflet": "^2.2.1",
  • "react-leaflet-draw": "0.16.0",
  • "leaflet.markercluster": "^1.4.1",
  • "react-leaflet-markercluster": "^2.0.0-rc3",

@yuzhva
Copy link
Owner

yuzhva commented Sep 1, 2020

There is a new version of react-leaflet-markercluster available - v2.0.0

Did you try to remove -rc3 and use the latest one?

yarn remove react-leaflet-markercluster
yarn add react-leaflet-markercluster

@NicoTechInc
Copy link

Hi all! I get the same issue. I'm using leaftlet to make some panels in grafana. First time I load my map, everything is fine, but if I go into another page with a map and then come back to my clustered map it's not reconizing my instanceof LatLngBounds in this code:

function toLatLngBounds(a, b) {
if (a instanceof LatLngBounds) {
return a;
}
return new LatLngBounds(a, b);
}

@Riuborth
Copy link

Riuborth commented Nov 3, 2020

Hi !

i've the same problem but i'm using react-leaflet 3.0.0.
How long take release new version of react-leaflet-markercluster?
There is another pluging like this?

@yuzhva
Copy link
Owner

yuzhva commented Nov 3, 2020

Hello, @Riuborth

Currently, this wrapper does not work with react-leaflet v3 - the issue is already created

I will take a look at how it could be implemented with v3 during those weekends.

any contribution is welcome

UPD:
The latest version with support of react-leaflet v3.0 available as a candidate release:

yarn add react-leaflet-markercluster@next # yarn
npm install react-leaflet-markercluster@next # npm

@asgaraliyev
Copy link

Temporary version:

import { MapLayer, withLeaflet } from "react-leaflet";
import L from "leaflet";

require("leaflet.markercluster");

class MarkerClusterGroup extends MapLayer {

  createLeafletElement(props) {
    const el = new L.markerClusterGroup(props);
    this.contextValue = {
      ...props.leaflet,
      layerContainer: el
    };
    return el;
  }

}

export default withLeaflet(MarkerClusterGroup);

import { withLeaflet,Marker} from "react-leaflet";
Attempted import error: 'withLeaflet' is not exported from 'react-leaflet'.

@yuzhva
Copy link
Owner

yuzhva commented Nov 24, 2020

Attempted import error: 'withLeaflet' is not exported from 'react-leaflet'.

@asgaraliyev In case, if you are using v3 of react-leaflet - that example is outdated, as it has been written for v2.

@sumeyradavran
Copy link

I am having similar problem with v3.

'MarkerClusterGroup' cannot be used as a JSX component.
Its instance type 'MarkerClusterGroup' is not a valid JSX element.
Type 'MarkerClusterGroup' is missing the following properties from type 'ElementClass': render, context, setState, forceUpdate, and 3 more.ts(2786)

Here is a versions I use.

@drkpkg
Copy link

drkpkg commented Dec 4, 2020

I am having similar problem with v3.

'MarkerClusterGroup' cannot be used as a JSX component.
Its instance type 'MarkerClusterGroup' is not a valid JSX element.
Type 'MarkerClusterGroup' is missing the following properties from type 'ElementClass': render, context, setState, forceUpdate, and 3 more.ts(2786)

Here is a versions I use.

Same problem, cannot visualize the map.

@AliBayatpour
Copy link

I have the same problem:
'MarkerClusterGroup' cannot be used as a JSX component.
Its instance type 'MarkerClusterGroup' is not a valid JSX element.
Type 'MarkerClusterGroup' is missing the following properties from type 'ElementClass': render, context, setState, forceUpdate, and 3 more.ts(2786)
here are packages versions:
"leaflet": "^1.7.1",
"react-leaflet": "^3.0.2",
"react-leaflet-markercluster": "^3.0.0-rc1",
"leaflet.markercluster": "^1.4.1",

I'll be very thankful if anyone helps :)

@moshkainer
Copy link

@AliBayatpour -
adding:

declare module 'react-leaflet-markercluster' {
import { Component } from 'react';

// eslint-disable-next-line react/prefer-stateless-function
export default class MarkerClusterGroup extends Component { }

}

to a global.d.ts file, fixed the "'MarkerClusterGroup' cannot be used as a JSX component" for me.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests