How to display a variety of JSON data in different templates with unique variables using angularjs

I am curious about the best approach to handling a response that contains various types of objects presented like this:

[
{"nodeClass":"Entity", "text":"foo","entityfield":"booz"},
{"nodeClass":"User","username":"bar","userfield":"baz"}
]

Each type of object requires its own template:

For Entities:

<div class="{{nodeClass}} capsule">{{entity.text}}:{{entity.entityfield}}</div>

For Users:

<div class="{{nodeClass}} capsule">{{user.username}}:{{user.userfield}}</div>

How can I structure the code using AngularJS elements (such as ng-repeat) to dynamically use the correct templates based on the value of "nodeClass"? It's important not to create new conditional templates unless absolutely necessary.

Edit: I have come across these resources: and if else statement in AngularJS templates and Dynamically displaying template in ng-repeat directive in AngularJS? However, they don't quite meet my specific requirements. The last one comes close, but my templates often include different variable names.

Thank you!

Answer №1

One method involves utilizing a dynamically created ng-include URL

Markup

  <div ng-repeat="item in data">
    <div ng-include="getContentUrl(item.nodeClass)"></div>
  </div>

Templates

  <script type="text/ng-template" id="partials/Entity.html">
    <h3>Entity Template , text= {{item.text}}</h3>
  </script>
  <script type="text/ng-template" id="partials/User.html">
    <h3>User Template , username ={{item.username}}</h3>
  </script>

JavaScript

app.controller('MainCtrl', function($scope) {
  $scope.data=[{"nodeClass":"Entity", "text":"foo"},{"nodeClass":"User","username":"bar"}];
  $scope.getContentUrl = function(nodeClass){
    return 'partials/'+nodeClass +'.html';
  }
});

VIEW DEMONSTRATION

Answer №2

If you want to dynamically update a template in your application, one approach is to fetch the `template.html` in the background using `$http`, parse it, and replace instances of variable names that don't match your `ng-repeat` variable name. Then, pass this edited HTML to a directive or controller template that contains the `ng-repeat` in its template. You can insert the modified HTML using `$('#elem').html(newHtml);` and then invoke `$compile` on the updated element.

For example, consider the template you retrieve:

controller1/template1.html

<h1>{{item.data}} - {{item.name}}</h1>

And the template where the repeater exists:

controller1.html

<p>This is the view for controller 1.</p>

<div id="repeater" ng-repeat="thing in vm.items">

</div>

The process of fetching the template, replacing the desired strings, and recompiling the template can be done as follows:

controller1.js

function Controller1($scope, $http) {
    var vm = this;

    vm.items = [{name: 'item1', data: 123}, {name: 'item2', data: 456}];

    var templateReplacement = '{{thing.';
    $http.get('controller1/template1.html')
        .then(function success(response) {
            var newHtml = response.data.replace(/{{item./g, templateReplacement);
            var repeaterElem = $('#repeater');

            $(repeaterElem[0]).html(newHtml);

            $compile(repeaterElem)($scope);
    }, function failure(reason) {
            console.log(reason);
    });
}

You can see an example of this implementation in action with this Plunk demo.

Answer №3

In order to customize the data from the service before it is rendered on the view, I utilize ng-if to selectively display HTML elements:

<div ng-repeat="data in dataset">
  <div
    class="capsule"
    ng-class="data.nodeClass"
    ng-bind="data.text"
    ng-if="data.nodeClass==='Entity'"></div>
  <div
    class="capsule"
    ng-class="data.nodeClass"
    ng-bind="data.username"
    ng-if="data.nodeClass==='User'"></div>
</div>

Click here for a modified version on Plunker Created by tpie

Answer №4

I developed a custom directive that accepts two attributes - one for defining the template and the other for passing relevant data to the template.

The template selector value is passed through a switch statement to determine the appropriate template and organize the data accordingly. Example Link

Custom Directive:

app.directive('templateSelector', function($compile) {
  return {
    restrict: 'A',
    scope: {},
    link: function(scope, el, attr) {
      console.log(attr.tClass, attr.tVals)
      var template ='';
      scope.data = angular.fromJson(attr.tVals);
      switch (attr.tClass) {
        case 'Entity':
          template = '<div><h1>Entity Class Template</h1>{{data.text}}</div><hr/>';
          break;
        case 'User':
          template = '<div><h1>User Class Template</h1>{{data.username}}</div><hr/>';
          break;
      }
      $template = angular.element(template);
      $compile($template)(scope);
      el.append($template); 
    }  
  }
})

HTML Usage:

<div ng-repeat="d in dataset">
    <div template-selector t-class="{{d.nodeClass}}" t-vals="{{d}}"></div>      
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Display or conceal a div based on the size of the screen using HTML and CSS

Hey there, I recently finished my first React Project and I’m wondering if there’s a way to hide the 'side-menu' section on mobile screens using CSS. Any suggestions? <div className='side-menu'> <SiderComponent /> < ...

Issue encountered while attempting to retrieve data from a local json file due to Cross-Origin Resource Sharing

I'm attempting to fetch and display the contents of a JSON file on a webpage, but I'm encountering this error message: Access to XMLHttpRequest at 'file:///C:/Users/bobal/Documents/htmlTry/myData.json' from origin 'null' has ...

Navigate to a new tab using this.router.navigate

Is there a way to redirect the user to a specific page with ${id} opening in a new tab, after clicking a button in an angular material dialog box? I want to leave the dialog box open while querying the new page. Currently, the redirect happens but not in a ...

Recreating dropdown menus using jQuery Clone

Hey there, I'm facing a situation with a dropdown list. When I choose "cat1" option, it should display sub cat 1 options. However, if I add another category, it should only show cat1 options without the sub cat options. The issue is that both cat 1 a ...

Javascript function to deselect all items

One of my functions is designed to reset all checkbox values and then trigger an AJAX request. However, there are instances when the function initiates before the checkboxes have been unchecked. function clear() { $("#a").prop("checked", false); $("#b ...

Steps for correctly invoking a function based on input value conditions

Lately, I've been developing a new website geared towards serving as a platform for various travel agencies to showcase their tour packages. The homepage features a functional filter section that enables users to search for offers based on different ...

Send an array of JSON objects representing table rows to an MVC controller

I was attempting to find a solution for a problem. Within the View: var data = [{ "MissionSheetMasterId": MS_MasIds, "EmployeeId": EmpIds, "PaidQty": Qtys, "PaidAmount": Amount }]; console.log(data); $.ajax({ url: '@Url.Action(" ...

Failed Attempt to Execute React Native Application using Command Prompt (iOS)

I'm currently working through the React Native tutorial found on their official website. During my project building process, I utilized the following command: react-native run-ios An error was encountered: Found Xcode project TestProject.xcodeproj ...

Having trouble with my React App compiling media files

I'm currently working with create-react-app and using a Data.js file where I define objects with properties that are spread as props in a tag. However, when I run npm start or deploy my application, the image doesn't show up. It seems like the co ...

Get rid of any empty space in the image preview icon

Is there a way to eliminate the white space that appears when mixing landscape and portrait images? I want the images to move up and fill the space, even if they don't align perfectly. Additionally, I would like the images to resize based on the scal ...

The correct method for accessing descendants in THREE.js in the latest version, r68

As of the release r68, the getDescendants() method has been removed from the THREE.Object3D API. How should we now achieve the same functionality without any warning message being provided? ...

Unable to utilize the resolved value received from a promise and returned from it

Within the code snippet below, I am retrieving a Table object from mysql/xdevapi. The getSchema() and getTable() methods return objects instead of promises. The purpose of this function is to return a fulfilled Table object that can be used synchronously i ...

Activate the "order evaluation" trigger on the checkout page in Woocommerce

I have implemented the Woocommerce Advanced Shipping plugin created by Jeroen Sormani for managing shipping methods, along with the WooCommerce Pay for Payment plugin developed by Karolína Vyskočilová to add a fixed €5 fee to the "cash on delivery" pa ...

What is the best way to convert a JSON array into a PostgreSQL array type?

Working with arrays in PostgreSQL has been quite straightforward for me, but I've hit a roadblock when trying to parse JSON data into an array column type. The JSON data I'm dealing with includes a property with an array value: "problems&qu ...

How does the Rx subscribe function maintain its context without the need to explicitly pass it along

Currently, I am utilizing Rx with Angular2 and making use of the Subscribe method. What intrigues me is that the callbacks of the method are able to retain the context of the component (or class) that initiated it without needing any explicit reference pas ...

Tips for accessing the information received from an AJAX call

When making an AJAX post request for processed data from the database in the form of an array [value1, value2, value3,...,valueN], I aim to use it on a ChartJS object. Here is the AJAX Request: $(document).ready($.post('callMeForAJAX.jsp', func ...

Basic HTML code that displays either one or two columns based on the width of the screen

My monitoring website displays dynamic rrd graphs in png format with fixed dimensions. I am looking to adjust the layout based on browser window size - showing the graphs in 1 column if the width is below a certain threshold, and in 2 columns if it exceed ...

What are the steps for importing KnockOut 4 in TypeScript?

It appears straightforward since the same code functions well in a simple JS file and provides autocompletion for the ko variable's members. Here is the TypeScript code snippet: // both of the following import lines result in: `ko` undefined // impo ...

following the history.back() function call, the subsequent codes are executed

<?php $ok_register = 0; if($ok_register != 1) { ?> <javascript type="text/javascript"> alert("1"); history.back(); </javascript> <?php } ?> <javascript type="text/javas ...

When trying to locate an item in an array within a VUE application, it may result in

I've got this code snippet that successfully finds the item details in an array: var findGroupId = medias.find(medias => medias.group_name === this.groupName) The medias variable is an array. When I run console.log(findGroupId), I get this result ...