skip to Main Content

To reduce my last question (it was a bit complicated). Is it possible to change the names of "array objects" dynamically?

I have a list of variables (structure must stay like this way):

var markers = []
var markerHouse = ... markers.push(markerHouse);
var markerAnimal = ... markers.push(markerAnimal);
var markerCar = ... markers.push(markerCar);
// aso.

I tried lots of ways to change the array object names, like this one:

var NewMarkers = "markerHouse, markerAnimal"; // string content, generated by a function
var NewMarkersArray = NewMarkers.split(","); // create array of this string
var NewGroup = L.layerGroup([NewMarkersArray]); // request for array of objects

The result of NewGroup is:

L.layerGroup(["markerHouse", "markerAnimal"]);

And I get a "TypeError: cannot use ‘in’ operator to search for "_leaflet_id" in "markerHouse" …

But what I need is:

L.layerGroup([markerHouse, markerAnimal]);

4

Answers


  1. Do you need eval?

    L.layerGroup([eval("markerHouse"), eval("markerAnimal")]);
    
    Login or Signup to reply.
  2. Using eval() as suggested in other questions is considered a bad practice.

    The most straightforward way to retrieve a global variable by it’s string name is from ‘window’. A global variable is actually a property of the ‘window’ object.

    So you could do:

    L.layerGroup( [ window["markerHouse"], window["markerAnimal")] ]);
    

    And with dynamic variable names:

    var dynamicallyGeneratedArrayOfVarNames = "markerHouse,markerAnimal".split(',');
    L.layerGroup( [ window[dynamicallyGeneratedArrayOfVarNames[0]], window[dynamicallyGeneratedArrayOfVarNames[1])] ]);
    

    See snippet below:

    var markerHouse = 'markerHouse content';
    var markerAnimal = 'markerAnimal content'
    
    console.log(window['markerHouse']);
    console.log(window['markerAnimal']);
    
    // And with dynamically retrieved names
    var NewMarkers = "markerHouse, markerAnimal"; // string content, generated by a function
    var NewMarkersArray = NewMarkers.split(", "); // create array of this string
    console.log(window[NewMarkersArray[0]])
    console.log(window[NewMarkersArray[1]])

    Still, if you have the luxury of refactoring the initial code, the best practice would be to store the variables by name on creation e.g.:

    const myvars = {}
    myvars.markerHouse = "any type of marker house data"
    myvars.markerAnimal = "any type of marker animal data"
    
    L.layerGroup( [ myvars["markerHouse"], myvars["markerAnimal")] ]);
    
    Login or Signup to reply.
  3. Keep your values in an object:

    const allMarkers = {
        house: whatever,
        animal: whatever,
        boat: whatever,
        // ...
     };
    
     let markerNames = ["house", "boat"];
    
     let markers = markerNames.map(name => allMarkers[name]);
    

    Then:

      let newGroup = L.layerGroup(markers);
    

    The allMarkers object contains the actual values corresponding to the named variables in your original code. They can be accessed by name dynamically because objects in JavaScript inherently provide that feature. The list of marker names can therefore be transformed into a list of the actual values with that simple .map() call.

    Login or Signup to reply.
  4. If you really can’t change what you’ve got, then I’d probably maintain a map of keys for every variable.

    const vars = {
      'markerHouse': markerHouse,
      'markerAnimal': markerAnimal,
    };
    

    Or even nicer:

    const vars = {markerHouse, markerAnimal};
    

    Then:

    var NewGroup = L.layerGroup(NewMarkersArray.map(v => vars[v]));
    

    If that’s infeasible, then you’ll have to use eval or window[‘markerHouse’]. Those both feel terrible though and suggest has gone wrong somewhere along the way.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search