This reference is wrong inside Drupal.Leaflet.prototype.create_json

Created on 27 July 2023, 11 months ago
Updated 20 November 2023, 7 months ago

Problem/Motivation

Using leaflet service provided by the module to display maps containing geojson feature, the javascript is crashing while attempting to create the json feature because a reference to this is wrong when it is trying to call feature_bind_tooltip and feature_bind_popup on the object hosting the function.

Uncaught TypeError: this.feature_bind_tooltip is not a function
onEachFeature leaflet.drupal.js:872
addData GeoJSON.js:128
create_json leaflet.drupal.js:884
create_geometry leaflet.drupal.js:530
create_feature leaflet.drupal.js:556
add_features leaflet.drupal.js:381

Steps to reproduce

Create a map containing geoJson features and render them with leaflet service's leafletRenderMap method.

Proposed resolution

Fix the reference to "this" in Drupal.Leaflet.prototype.create_json, currently it is pointing inside the function lJSON.options.onEachFeature itself instead of the parent's.

Remaining tasks

Review & apply

User interface changes

None

API changes

None

Data model changes

None

๐Ÿ’ฌ Support request
Status

Fixed

Version

10.0

Component

Code

Created by

๐Ÿ‡ซ๐Ÿ‡ทFrance B2F

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @B2F
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F
  • Status changed to Needs review 11 months ago
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F
  • Issue was unassigned.
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F
  • ๐Ÿ‡ฉ๐Ÿ‡ฐDenmark ressa Copenhagen

    Thanks for working on this. I see a similar syntax for "Leaflet Feature (Point or Geometry)". Perhaps you can check if it should also be updated? https://git.drupalcode.org/project/leaflet/-/blob/10.0.x/js/leaflet.drup...

  • Assigned to B2F
  • Status changed to Active 11 months ago
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F

    I don't think calls to this in Drupal.Leaflet.prototype.create_feature are an issue since they are called at the prototype's function level. Furthermore I would probably have seen the error also there if it was necessary to modify create_feature, my patch alone seems to resolve the issue mentioned in the description.

  • ๐Ÿ‡ฉ๐Ÿ‡ฐDenmark ressa Copenhagen

    Thanks for checking @b2f, it's much appreciated.

  • Status changed to Postponed: needs info 11 months ago
  • ๐Ÿ‡ฎ๐Ÿ‡นItaly itamair

    thanks @b2f for reporting this.

    But the Drupal.Leaflet.prototype.create_json method/property was really never validated/used/debugged since I started maintaining the Leaflet module (for D8), and I think there could be more issues in its implementation, than the once you point with your patch.

    I don't exactly get when you write:

    Using leaflet service provided by the module to display maps containing geojson feature ...

    How are you doing that?
    Because I am not aware of any WKT definition with "json" type ...

    It would be very interesting for me to understand how to re-create your use case,
    but I don't know how to generate it, and have here: https://git.drupalcode.org/project/leaflet/-/blob/10.0.x/js/leaflet.drup...
    a feature that has feature.type == "json".

    Could you provide all the code you are using in this issue context?
    Or at least the the whole feature object definition, so that I could inject in the js console workflow and recreate your use case and debug and (potentially) fix all the Drupal.Leaflet.prototype.create_json function?

    Thanks a lot ...

  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F

    Hello itamair,

    I made a wrapper around leafmet.service with the following method:

    
      /**
       * @param array $geoJsons
       * @param string $mapName
       *   Voir fei_maps_leaflet_map_info().
       * @param string $mapHeight
       *
       * @return array
       *   Render.
       */
      protected function buildGeoJsonMap(array $geoJsons, $mapName = 'carte_pour_geojsons', $mapHeight = '800px') {
    
        $this->addGeojsonWarnings($geoJsons);
    
        $map = leaflet_map_get_info($mapName);
        $features = [];
        foreach ($geoJsons as $tid => $geojson) {
          $geoJsonArray = json_decode($geojson, TRUE);
          // Keep the related tid reference for the click event:
          $geoJsonArray['tid'] = $tid;
          $features[] = [
            'type' => 'json',
            'json' => $geoJsonArray,
            // @see https://www.drupal.org/project/leaflet/issues/3186029#comment-13927181
            'events' => [
              'click' => 'Drupal.manageGeojsonClick',
            ],
          ];
        }
        return $this->leaflet->leafletRenderMap($map, $features, $mapHeight);
      }
    
    

    The $geoJsons array is containing typical geojson strings as such:

    "{"type": "Feature", "properties": { "scalerank": 1, "featurecla": "Admin-0 country", "labelrank": 2.0, "sovereignt": "Argentina", "sov_a3": "ARG", "adm0_dif": 0.0, "level": 2.0, "type": "Sovereign country", "admin": "Argentina", "adm0_a3": "ARG", "geou_dif": 0.0, "geounit": "Argentina", "gu_a3": "ARG", "su_dif": 0.0, "subunit": "Argentina", "su_a3": "ARG", "brk_diff": 0.0, "name": "Argentina", "name_long": "Argentina", "brk_a3": "ARG", "brk_name": "Argentina", "brk_group": null, "abbrev": "Arg.", "postal": "AR", "formal_en": "Argentine Republic", "formal_fr": null, "note_adm0": null, "note_brk": null, "name_sort": "Argentina", "name_alt": null, "mapcolor7": 3.0, "mapcolor8": 1.0, "mapcolor9": 3.0, "mapcolor13": 13.0, "pop_est": 40913584.0, "gdp_md_est": 573900.0, "pop_year": -99.0, "lastcensus": 2010.0, "gdp_year": -99.0, "economy": "5. Emerging region: G20", "income_grp": "3. Upper middle income", "wikipedia": -99.0, "fips_10": null, "iso_a2": "AR", "iso_a3": "ARG", "iso_n3": "032", "un_a3": "032", "wb_a2": " [...]

    Looks like it was taken straight out of a dataset such as: https://github.com/datasets/geo-boundaries-world-110m/blob/master/countr...

    Then the map is displayed in a typical controller through the method above. Not sure if you need more info about the map settings for example ?

  • Issue was unassigned.
  • Status changed to Active 11 months ago
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F
  • Status changed to Fixed 10 months ago
  • ๐Ÿ‡ฎ๐Ÿ‡นItaly itamair

    thanks @b2f for you detailed feedback.
    I reproduced your use case (that looks very specific and arbitrary to me, as not documented and advised anywhere ...) and I could somehow forced the adjustment of the Drupal.Leaflet.prototype.create_json method/function,
    BUT I really found myself in a not existing use case for the definition of Geofield features types (json type doesn't exists in WKT formats ... ).

    Hence I am going to completely remove it from next Leaflet module release, on one side ...

    As it looks you are "simply" trying to inject GeoJson resources in a Drupal Leaflet Map View, I strongly suggest to refer to (and follow) this Leaflet Support issue I created both for this purpose and for coping more general users need: Adding GeoJson resource into a Drupal Leaflet Map View ๐Ÿ’ฌ Adding GeoJson resource into a Drupal Leaflet Map View Needs review

    For more detailed information and guide on this, please refer to the following Leaflet Map GeoJson Demo page, and related instructions / insights ...

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly itamair
  • ๐Ÿ‡ฎ๐Ÿ‡นItaly itamair
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F

    Leaflet Map View as in Views module ?

    Sorry but no we were not using the Views module, as described in my previous comment I explained "The map is displayed in a typical controller through the method above".

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly itamair

    Well, it doesnโ€™t change anything.
    Whichever is the way you generate the Drupal Leaflet map you could (and should) use that approach to add/inject GeoJson resources tanto that โ€ฆ

  • Automatically closed - issue fixed for 2 weeks with no activity.

  • Status changed to Fixed 8 months ago
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F

    Could you please explain where to go from the above because your d10 update breaks the geojson layers in our case.

    Can you kindly please be more specific with ?

    Whichever is the way you generate the Drupal Leaflet map you could (and should) use that approach to add/inject GeoJson resources into that โ€ฆ

    ?

    I mean can't you see how much we were apparently relying on this feature ?
    It's like if I got punished to open this issue because you wouldn't have seen this in the first place ? Come on' ...

  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F
  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F
  • ๐Ÿ‡ฎ๐Ÿ‡นItaly itamair

    @b2f ok ... probably I was too quick in simply removing this Drupal.Leaflet.prototype.create_json, just because I couldn't figure out any valid use case for this, and couldn't get your successfully way in doing that.

    Still I hope you could give better evidence of it (may be with a more detailed description, with some code Gists i.e.)and thus give a practical contribution and guidance to the Drupal Leaflet module community ...

    Anyway you persuaded me to rollback the deletion of the Drupal.Leaflet.prototype.create_json method and apply (a slightly different version of) your #2 patch, but still crediting you
    (no body wants to punish anybody ... may be it was just some misunderstanding).

    The following commits:
    https://git.drupalcode.org/project/leaflet/-/commit/59012fdb03e47354da02...
    https://git.drupalcode.org/project/leaflet/-/commit/dd342f17ea68a8499136...
    https://git.drupalcode.org/project/leaflet/-/commit/09f21141549c5a5604bb...

    are now into the 10.0.x-dev branch and are going to be part of the incoming 10.2.2 new Leaflet module release.

  • ๐Ÿ‡ซ๐Ÿ‡ทFrance B2F

    Thanks for listening, because, actually until now I just applied a patch myself to rollback the changes, otherwise it would have needed a huge rewrite.

    Still I hope you could give better evidence of it (may be with a more detailed description, with some code Gists i.e.)and thus give a practical contribution and guidance to the Drupal Leaflet module community ...

    I already specifically asked you if you needed more informations about my implementation in comment #10, https://www.drupal.org/project/leaflet/issues/3377403#comment-15190179 ๐Ÿ’ฌ This reference is wrong inside Drupal.Leaflet.prototype.create_json Fixed

    The thing is there is not a single line of custom JS nor the need to inject a Drupal setting in this case, neither the use of Views module. It's just a controller which returns a standard render array, and it works as is with the leafletRenderMap from the leaflet service, I thought it was clear from my code snippet ... What is missing from my example above ?

Production build 0.69.0 2024