Search code examples
javascriptjqueryscopehandlebars.jsecmascript-5

Select predefined variable using string returned from a function


I was wondering, whether this was even possible: I have a webpage with a URL along the lines of this: ".../product.html?id1",

and using Handlebars.js I am trying to render from a js file with products:

$(function() {
  var id1 = {
    name: "Module 14/88",
    ID: "445856",
    desc: "some text"
  };
  var id2 = {
    name: "Kolp-display",
    ID: "445857",
    desc: "some other text"
  };
  //..... // about 60 more, but the same format
  function prid() {
    var full_url = document.URL;
    var url_array = full_url.split('?');
    var last_segment = url_array[url_array.length - 1];
    return last_segment;
  };

  var theTemplateScript = $("#template").html();
  var theTemplate = Handlebars.compile(theTemplateScript);
  $(".panel").append(theTemplate(prid())); // this does not work
});

And the template is embedded into HTML and works when I set the variable manually. It always renders just one product at a time, like a product page.

<script id="template" type="text/x-handlebars-template">
    <div class="panel-heading">
        <h2><span>{{name}}</span></h2>
        <p><span>{{ID}}</span></p>
    </div>
    <div class="container-fluid">
        <div class="row" style="margin-top: 2rem">
            <div class="col-sm-7 ">
                <p>{{desc}}</p>
            </div>
        </div>
    </div>
</script>

So essentially, I am trying to select a variable to be rendered (appended) from the id in URL, to be included in the part of:

$(".panel").append(theTemplate(___selected_variable_from_id_in_URL___));

So the value returned by prid() in this case is id1, and so I want the id1 array to be used by Handlebars. As the variable is alredy defined, I just want to use the string from the prid() function as an identifier for the variable. Is there a way to do this, I do not know and search has so far not been helpful.


Solution

  • You would need to use eval based on the code that you have currently.

    The preferred approach would be is to have your entire data set as part of a single object, where id would be the keys and the, data the corresponding id's values.

    var data = {
      id1: {
        name: "Module 14/88",
        ID: "445856",
        desc: "some text"
      },
      id2: {
        name: "Kolp-display",
        ID: "445857",
        desc: "some other text"
      }
    };
    

    Then you would just have to do data[prop()] to pull in the right data set.

    Other other approach which I do not recommend is storing the variables as part of the window object or using eval.

    Accessing object from the global scope

    // or declare them in the global scope, which can then be accessed 
    // from the same object
    window.id1 { name:"Module 14/88", ID:"445856", desc:"some text" };
    window.id2 { name:"Kolp-display", ID:"445857", desc:"some other text" };
    
    window[prop()]
    

    This can introduce variable leaks in the global namespace. It is always better to avoid using global variables.

    Using eval

    eval(prop())