Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
I have a DOM element with children that contain placeholders. I need to loop through the object in the JSON array and replace the placeholders with corresponding keys in the array.

What I have tried:

Here is the html element I wish to prototype:
HTML
<pre><div id="foods">
  <div class="food-menu">
    <img src=/{{image}}>
    <p>{{name}}</p>
    <p>{{price}}</p>
  </div>
</div>


Then my JS code is as follows:

JavaScript
var prototype = $(".food-menu").eq(0);
            
            data.forEach(function(b) {
      var newFood = prototype.clone().appendTo($("#foods"));

      newFood.html().replace(/(\{\{(\w+)\}\})/gi, function(matches, istMatch) {
        return b[istMatch.toString()];
      });

      data = [{
        "_id": "588b1fcb74e6c500d0d06bf8",
        "type": "cakes",
        "name": "white cake",
        "price": "53.115585580044765",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bf9",
        "type": "cakes",
        "name": "strawberry cake",
        "price": "70.97793026186996",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfa",
        "type": "cakes",
        "name": "cupcakes",
        "price": "49.96683058076812",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfb",
        "type": "cakes",
        "name": "chocolate cake",
        "price": "44.344115951103035",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfc",
        "type": "cakes",
        "name": "berry cake",
        "price": "47.17550216232682",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfd",
        "type": "drinks",
        "name": "whiskey",
        "price": "0.028678076457766544",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bfe",
        "type": "drinks",
        "name": "vodka",
        "price": "58.894390375434135",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06bff",
        "type": "drinks",
        "name": "juice",
        "price": "77.30969339423659",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c00",
        "type": "drinks",
        "name": "heineken",
        "price": "65.3927295846118",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c01",
        "type": "drinks",
        "name": "coke",
        "price": "2.2636518712426",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c02",
        "type": "snacks",
        "name": "popcorn",
        "price": "64.2930268142774",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c03",
        "type": "snacks",
        "name": "hamburger",
        "price": "48.89626145534767",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c04",
        "type": "snacks",
        "name": "digestive biscuits",
        "price": "93.3497353037074",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c05",
        "type": "snacks",
        "name": "chips",
        "price": "63.459315048229016",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c06",
        "type": "snacks",
        "name": "chin chin",
        "price": "9.608763915240747",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c07",
        "type": "soups",
        "name": "Ogbono",
        "price": "64.40284806037988",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c08",
        "type": "soups",
        "name": "egusi",
        "price": "99.68697142243515",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c09",
        "type": "soups",
        "name": "efo riro",
        "price": "89.32812199871545",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c0a",
        "type": "soups",
        "name": "Edikaikong",
        "price": "29.871174566764623",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c0b",
        "type": "soups",
        "name": "bitter leaf",
        "price": "40.503677589544786",
        "__v": 0
      }, {
        "_id": "588b1fcb74e6c500d0d06c0c",
        "type": "soups",
        "name": "afang",
        "price": "36.13059103755023",
        "__v": 0
      }]


Demo fiddle is here Edit fiddle - JSFiddle[^]
It just replaces nothing :(
Posted
Updated 6-Mar-17 9:57am
Comments
Bryian Tan 16-Feb-17 10:47am    
the code is not running, there are syntax errors
nmeri17 16-Feb-17 14:53pm    
I've modified the code. No errors yet it does not replace. New fiddle https://jsbin.com/nunapo/edit?js,console,output
Richard Deeming 16-Feb-17 11:47am    
You might want to look at an existing library like Handlebars.js[^], rather than trying to roll your own.
Karthik_Mahalingam 16-Feb-17 22:38pm    
possible solution..
nmeri17 17-Feb-17 8:43am    
It's just a tiny function that doesn't require a whole library. I eventually solved it. The problem was I was referencing the 1st match instead of the 2nd one. See updated fiddle https://jsbin.com/nunapo/edit?js,output

1 solution

The current, more robust function looks like this

JavaScript
function renderConstruct(datas, target, prototype) {
				$(datas).each(function(index, data) {
					var clone = prototype.first().clone(), name = clone.show().unwrap().html().replace(/\{\{(\w+)\}\}/gi, function (match, $1) {
						
						// resetting the value of `username_search` to `username`
						if (data["username"] !== undefined) {
							data["username_search"] = data["username"];
						}

						if (data[$1] != undefined) {
							return data[$1];
						}
							return "";
						});
						target.append($("<li/>").html(name));
				});

				// if the available image is unavailable, serve default
				$.each($("img", target), function(index){
					var that = $(this);

					/* wrapping this in a timeout cuz the instant images are loaded into the dom,
					* they arent fetched from the server immediately, hence their default naturalHeight == 0 so it needs
					* some time before confirming its nonexistence and replacing it with the default
					*/
					setTimeout(function() {
						if (that[0].naturalHeight == 0) {
							that.attr("src", "/images/default.jpg")
						}
					}, 1000);
				})

			}


As requested by @Karthik
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900