Link to home
Start Free TrialLog in
Avatar of Isaac
IsaacFlag for United States of America

asked on

Iterate Object with arrays

I am using handlebars and ran into an issue with trying to group by a category but I was able to fix that by using underscorejs.  Now my issue is using my object categorized into arrays into my template.  Here's an image of what I see in the developer tools:
User generated image
As you can see, it's an object with two arrays.  I got the data to show by doing the following but as you will see, it's not very efficient because there are actually have 6 categories and not just two.
<!-- Handlebar Js Template Starts Here -->
   
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.10/handlebars.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script type="text/javascript" src="../nrm/SiteAssets/projectMilestone.js"></script>

<script id="projectMilestone-template" type="text/x-handlebars-template">
 
<table border=1> 
 	<tr>
 		<th colspan="7">Milestones</th>
 	</tr>


	<tr>
		<td>Milestone Description</td>
		<td>Planned Date</td>
		<td>Revised Date</td>
		<td>Actual Date</td>
		<td>Type</td>
	</tr>
{{#Construction}}	
	<tr>
		<td>{{ MilestoneDescription}}</td>
		<td>{{ Planned_x0020_Date}}</td>
		<td>{{ Revised_x0020_Date}}</td>
		<td>{{ Actual_x0020_Date}}</td>
		<td>{{ Milestone_x0020_Type }}</td>
	</tr>
{{/Construction}}
 

	<tr>
		<td>Milestone Description</td>
		<td>Planned Date</td>
		<td>Revised Date</td>
		<td>Actual Date</td>
		<td>Type</td>
	</tr>
{{#Design}}	
	<tr>
		<td>{{ MilestoneDescription}}</td>
		<td>{{ Planned_x0020_Date}}</td>
		<td>{{ Revised_x0020_Date}}</td>
		<td>{{ Actual_x0020_Date}}</td>
		<td>{{ Milestone_x0020_Type }}</td>
	</tr>
{{/Design}}

</table>
 
</script>

<div id="projectMilestone"></div>

Open in new window


Here's my Javascript code:
//Loading items for handlebars to use
function loadSPItems() {
 var projNum = '402-CSI-001';
var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('Project Milestones')/items?$select=MilestoneDescription,Milestone_x0020_Type,Planned_x0020_Date,Revised_x0020_Date,Actual_x0020_Date&$filter=Title eq '"+projNum+"'";//,ProjectNumber,ApprovalStatus,ProjectExecutionStatus”;
console.log(endPointUrl);
var headers = { 
	"accept": "application/json;odata=verbose" 
}
 
jQuery.ajax({ 
	url: endPointUrl, 
	type: "GET", 
	headers: headers, 
	success: function (data) {
console.log(data);
	var groupData = _.groupBy(data.d.results, function(d){return d.Milestone_x0020_Type});
	
	console.log(groupData)

    	//1.Get the template source from the DOM
    	//returns final mark up with interpolation
		var source = $("#projectMilestone-template").html(); 
		
		//2. Compile the template source into a template *function*
		var profileTemplate = Handlebars.compile(source); 	
		//3. call our template function, passing in data to render the template with
		var renderTemplate = profileTemplate(groupData); 
		
		//4. Add our rendered HTML to the page
		$("#projectMilestone").html(renderTemplate)
}, 
	error: function (err) { 
	alert("Error Occured:" + JSON.stringify(err)); 
}
 
});
 
}
loadSPItems();

Open in new window

Avatar of HainKurt
HainKurt
Flag of Canada image

I could not get whats the issue here...
is there anything not working / wrong result / slowness?

if yes, which function/code needs to be fixed?
Avatar of Isaac

ASKER

I would like to loop through groupData in handlebars do what I did which is
{{#Construction}}	
	<tr>
		<td>{{ MilestoneDescription}}</td>
		<td>{{ Planned_x0020_Date}}</td>
		<td>{{ Revised_x0020_Date}}</td>
		<td>{{ Actual_x0020_Date}}</td>
		<td>{{ Milestone_x0020_Type }}</td>
	</tr>
{{/Construction}}
 

	<tr>
		<td>Milestone Description</td>
		<td>Planned Date</td>
		<td>Revised Date</td>
		<td>Actual Date</td>
		<td>Type</td>
	</tr>
{{#Design}}	
	<tr>
		<td>{{ MilestoneDescription}}</td>
		<td>{{ Planned_x0020_Date}}</td>
		<td>{{ Revised_x0020_Date}}</td>
		<td>{{ Actual_x0020_Date}}</td>
		<td>{{ Milestone_x0020_Type }}</td>
	</tr>
{{/Design}}

Open in new window


There are actually a potential of 7 categories.  I would rather loop through the object array instead of what I did above
Avatar of Isaac

ASKER

My group data is what you see in my initial question with "Construction" and "Design"
Avatar of Julian Hansen
So you Construction and Design are categories (2 of 6) and you are concerned with the efficiency of the handlebars solution where you have to specify a template for each category?

It looks like you need to change your data structure so that you have all your items under one array but ordered by the milestone type.
Avatar of Isaac

ASKER

I initially had all my items under one array but it was difficult to group by category.  I thought it would be easier this way but it seem I am wrong.
It is a trade off - you are using a templating library - which needs to iterate over a collection - but you have multiple collections.

Can you not create the array and then just sort it using a custom sort function - on category?
Avatar of Isaac

ASKER

If I do that, would I still be able to use the templating library or would I need to create the grouping functionality without the library?  Looks like Handlebars does not group out of the box
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Isaac

ASKER

Oh wow.  I had been in meetings all day and was going to respond with what the format was going to be, which is what I was working on before I saw this.
I will post that as a separate question.

BTW, I understand what you did.

Thank you!
You are welcome.
Avatar of Isaac

ASKER

I will post as another question, but do you think handlebars is the right solution for this.
User generated image
I am not the right person to ask. I either just write the JavaScript to do it if it is simple or use Angular or React.

Both of the previously mentioned will work - Angular is a framework so might be more difficult to migrate to React is a View library that would probably integrate better - depends on your long term requirements, time frames and knowledge of each.