I have an idea for a browser plugin which would manipulate Leaflet maps on third-party sites. But I'm stuck on a simple thing: I'm not sure how to discover Leaflet map DOM elements on a page, and then access the associated Leaflet map object.
Is $('.leaflet-container') a reliable way to find all map objects?
How to actually access the map object from that object, so I can do something like: $('.leaflet-container').eachLayer(...), which doesn't work.
This question is essentially the same as How can I get a leaflet.js instance using only a DOM object?, but the answer there was a workaround which doesn't help.
Yes, that should be sufficient, although it's not a documented behavior and could at least theoretically change in future versions of Leaflet
There's no way to do this. The reference to the map is owned by the code creating the map, and it could have discarded it or might be storing it in a location you do not have access to. Leaflet itself does not store a reference to the map anywhere where you can access it
On a side note, it is my opinion that you should rather let users of your code explicitly pass references to you, rather than you trying to automatically find references. See for example the inversion of control principle, where the caller supplies dependencies; Law of Demeter is also somewhat applicable - don't pry into other codes internals (unless you really, really have to).
OK, so this is a solution that could work, but it is brittle and limited. If you have a way to more directly find the reference, that's ideal.
I wanted to get a map reference where I do not want to modify upstream code; it's a one-off where brittleness is OK.
I know my map is going to be defined on the window.FOO scope (i.e. it's a global reference) and that it will be in the format map0000 where 0000 is a random number. So I constructed a quick function to scan the global window object's properties for variables matching this pattern.
window[Object.keys(window).find(key => key.substr(0,3) === "map")];
This returns a Leaflet map reference but could break if there is more than one map on the page. You could also add a validation that it's a real Leaflet map by testing it's properties.
Again, this is not ideal, but, if your use case is limited enough, it is one way to achieve this. Thanks!
Related
I want to create an object and hide some of its properties.
How do I do this?
For example, to this object:
console.log(new Path2D()); // Path2DÂ {} empty*
In this image, the console is very crowded and confusing.
It depends why you want to do that, it's hard to give a precise answer without more details. In most cases there is no need to hide properties (what are you afraid of?), but here are two ways if you really need to:
you can use Symbol properties (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol), that is new Path2D() would return an object where the keys are not strings but Symbols. This has the advantage that a user of this object can add its own properties to the object without risking clashing with internal properties that your library relies on. It is still possible for someone to access those properties, though, if they really want to.
You can hide things in a local variable in a closure. It is much more hidden than with Symbol properties, but it might require thinking about the API differently.
I am using angular leaflet, leaflet-draw and I am trying to get a circle (or other drawn object) object to see if a point on the map appears within it overtime. I need to use it in a separate service. How can I access the data for an object already drawn somewhere else in my angular code?
Found the answer. To access a drawn object in the way I was attempting, I had persisted the L.FeatureGroup object in my service. Inside this object is a layersDrawnItems sub-object. This object has a _layers array which contains the list of drawn objects.
They can then be accessed using the leaflet API. I still don't know how I was supposed to find this with the given documentation (unless I missed something completely obvious, which I am assuming I did, given that this would seem to be basic functionality) but if anyone else needs to know, here it is.
Relatively basic question but I can't find an answer. I've emailed Tealium as well, but thought I'd ask the masses here.
I want to explicitly set something within the s object, in this case s.referrer. When I set it in an extension, it doesn't take. Referrer isn't one of the things I can map directly to, so that's not an option.
I thought I could simply call out an s object assignment statement since I did it once before with s.linkTrackVars and it looked like it worked based on results in the reporting, but now, I decided to go check and the Tealium Web Companion claims there's nothing set there either.
How do I call out, in plain JS, setting something in the s object in Tealium?
This is possibly because since you're running your s-code within a Tealium SiteCatalyst tag, and it's not globally setting s on the window to anything anymore, by default.
If you want to change a particular value, do the following:
Create a new data layer value within the Tealium UI that'll be used to store your value (and generally aid in the graphical mapping)
In your extension, scoped to the tag, set the the value of that data layer value (b.[variable_name])
Create a new mapping within the SiteCatalyst tag and select the SiteCatalyst value to want to map to (referrer in your case). On the other side of the mapping, specify that data layer value you made a couple of steps ago
I'm trying to use OrderedMap.merge to store application state using reflux (specifically reflux-immutable), but I noticed this does not translate Objects into OrderedMaps, but regular Maps, which do not guarantee order when iterated over. There are several parts of my application where I need order to be retained, so I was wondering if there was a way to accomplish this using OrderedMap.merge or something like merge. I came up with this, but it's super ugly and relies on ripping source code out of Immutable.js, which I'm not comfortable with.
Does anyone have any other ideas? Thanks in advance.
I decided to solve this problem a different way, namely by explicitly converting the objects I needed to be ordered maps prior to invoking OrderedMap.merge on the entire store's state. This works because the definition of merge essentially ignores objects that are already immutable, so there's no risk of duplicate work and merge's functionality is retained without having to do all the silly hacked together stuff I was doing.
I have the following code which works under V2 and I am trying to move it over to V3.
The issue seems to be the access to the "this" object which holder the polyline to which the event is being added. (there are many such instantiations on the map so I don't necessary know which one is making the call when I receive the event, I can object the necessary information by passing this through the callbackArgs interface provided in V2)
I have read up on closures but I can't seem to see how I might apply them
GEvent.addListener(this.intLineObj , "click",
GEvent.callbackArgs(this, this.loadComments, null));
I was never able to find an answer to this one. I had to rewrite my code to access everything via an indexed global array. (not really what I wanted to do)