2

I have created a named map that gets data from a private table. I can load it into a Leaflet map and can change its marker-fill color placeholder using layer.setParams.

However, I cannot get interactivity to work. I want to be able to hover or click on a feature and do something useful.[1]

What do I need to do to make hover or click events fire?

Here is the named map json file

{
  "version": "0.0.1",
  "name": "mynamedmap",
  "auth": {
   "method": "open" 
  },
  "placeholders": {
      "color": {
        "type":"css_color",
        "default":"blue"
      }
  },
  "layergroup": {
    "version": "1.0.1",
    "layers": [{
      "type": "cartodb",
      "options": {
        "cartocss_version": "2.1.1", 
        "cartocss": "#layer { marker-fill: <%= color %>; }",
        "sql": "select * from mytable",
        "interactivity": ["cartodb_id"]
      }
    }]
  } 
}

Here is the javascript to create the layer:

cartodb.createLayer(map, {
        type: 'namedmap',
        user_name: 'myusername',
        options: {
          named_map: {
            name: 'myusername@mynamedmap'
          }
}})            
.addTo(map)
.done(function(layer) {
    console.log(layer.getSubLayerCount()); //prints '0'        
    layer.setParams('color', 'green'); // works to change marker color

    layer.on('featureClick', function(e, latlng, pos, data) {
      console.log(e, latlng, pos, data); //this never gets called
    });

  });

[1] "Something useful" could be as simple as open infowindow and display cartodb_id and feature name. Or it could mean "get cartodb_id for feature, pass it to my proxy where I can use curl to run some custom sql against my private table, then return json to the map and update display"

3

I feel a bit of an idiot for not figuring this out sooner. Here is the solution that worked for me.

Add the following line to the namedmap definition: layers: [{}]

The call to createLayer then looks like this:

cartodb.createLayer(this.map.baseMap, {
      type: 'namedmap',
      user_name: 'myusername',
      options: {
        named_map: {
          name: namedMap.name,
          layers: [{}]
})
.done(function (layer) {
  var subLayer = layer.getSubLayer(0);
  subLayer.setInteraction(true);

});

After doing so, you can add event handling like:

      subLayer.on('featureOver', function(e, latlon, pos, data, subLayerIndex) {
        console.log("hovered over");
        console.log(data);
      }); 

It would have been very helpful for me, as I have commented in another post on this forum, for more thorough documentation - a response there indicated that it is coming, which is great news, as CartoDb is fantastic.

1

I think you're missing enabling interaction. Try this:

layer.getSubLayer(0).setInteraction(true);
layer.on('featureClick', function(e, latlng, pos, data) {
    console.log(e, latlng, pos, data); //this never gets called
});
  • Thanks. That is certainly what works in cases where there are sublayers. However, it appears that sublayers do not exist when using named maps. As I mentioned in my post, getSubLayerCount() returns 0. I will post an answer shortly with my workaround, which is UTFGrid. I really would love a cartodb-native solution, though, as UTFGrid is a little clunky for my needs – susie derkins Jan 9 '15 at 3:02
  • Update - you were correct, although the answer was incomplete. It was my fault for failing to have sublayers as part of the named map layer definition, and I didn't realize that until now. The real problem was with a lack of subLayers, not so much with interaction, per se. I've upvoted your answer but selected my own as the correct one. – susie derkins Jan 10 '15 at 1:23
  • Oh, didn't realise of that! Thank you for the information. CartoDB documentation is updated every day, and including every case possible is hard, but I also feel named maps documentation lacks some tips. Working on it, any suggestion is appreciated :) – juanignaciosl Jan 10 '15 at 9:35
  • How does one choose which fields are queried on 'featureClick" ? using setInteractivity('fieldName') returns an error – jotamon Apr 21 '15 at 21:13
0

Note: this was my original answer before I actually solved my problem

In case anyone is having this problem - I haven't figured out how to do this using just cartodb.js, but my workaround is to use the UTFGrid Leaflet plugin. It's pretty simple to use. My main gripe is that when you change the parameters of the named map (by calling setParams()), the UTFGrid data becomes out of sync with the new features that are displayed. This isn't a problem with UTFGrid, per se.

This means you need to make another call to generate a new UTFGrid after you call setParams(). In case you're interested: in order to generate a new UTFGrid, you must get the updated layergroupid of the original CartoDB layer. This changes whenever you call setParams. It isn't updated until the resulting call to the server after setParams has returned. However, because there isn't (as far as I can tell) any way to tell when layer.setParams() has completed, I have resorted to using setTimeout to wait a little while. On the timeout, I can grab layer.layerToken and generate a new UTFGrid. Kind of kludgy.

This is the best I've come up with for now - please post a better answer if you have one! I really would like to be able to do this without the workaround. Seems like it should work natively through just CartoDb...if anyone more familiar with that wants to weigh in, please do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.