When should ng-repeat be utilized: only when the object type is an array?

I have a detailed object structure below:

$scope.document = 
 {
  "GENERAL_FIELDS": {
    "Source_Type": "custom",
    "Annotations": [
      "216/content/Factiva_CM_001/Proteins",
      "216/content/Factiva_CM_001/Fact"
    ],
    "Content": [
      "   Baculovirus; Budded virus; Ultrastructure; Cryo-EM;"
    ],
    "Title": [
      "Budded baculovirus particle structure revisited"
    ]
  },
  "stn": {
    "Document_Type": [
      "Journal",
      "Article"
    ]
  }
}

My goal is to display all the fields within "GENERAL_FIELDS" and "stn". The values of these fields can be either strings or arrays of strings. If it's an array, I want to iterate over each item and show the content. Below is my HTML markup:

<div id="titsec" class="comdocdet"  ng-repeat="(category, group) in document">
   <div ng-repeat="(key, value) in group">
      <div class="pTitle">
         {{key}}
      </div>
      <div class="contdesc">
         <div ng-if="Array.isArray(value)">
            <div ng-repeat="v in value">
               {{v}}
            </div>
         </div>
         <div ng-if="!Array.isArray(value)">
            {{value}}
         </div>
      </div>
   </div>
</div>

However, the ng-if="Array.isArray(value)" statement never evaluates to true and the array fields are shown as objects like: ["Journal","Article"]. What am I overlooking?

Answer №1

To implement this functionality in your controller, simply add the following code:

 $scope.isArray = angular.isArray;

Then, update your HTML like so:

<div ng-if="isArray(value)">
  <div ng-repeat="v in value">
    {{v}}
  </div>
</div>
<div ng-if="!isArray(value)">
            {{value}}
</div>

Answer №2

It is recommended to refrain from directly accessing a method on the Array object within the template. Instead, it is suggested to handle this in the controller. For instance:

<div ng-if="vm.isValueAnArray(value)">
  // Some html
</div>

Your controller can contain the following logic:

function isValueAnArray(val) {
  return Array.isArray(val);
}

While untested, the best practice is to keep the logic in the controller rather than the template.

Answer №3

Dealing with Scoping in Templates

When it comes to scoping, the template's scope is relative to the controller's scope. This means that references to variables like $scope.Array will look for them within the controller's scope.

To address this issue, one approach is to utilize

ng-if="window.Array.isArray(value)"
. For a practical demonstration, refer to the example provided below.

Alternatively, you could set $scope.Array = Array.prototype in the controller. By doing so, you eliminate the need to explicitly reference window before calling functions like Array.isArray().

A different strategy involves creating an alias for Array.isArray() within the controller's scope:

$scope.isValueAnArray = Array.isArray;

This way, you can simply invoke the function to determine whether a given value is an array or not.

angular.module('ang', [])
  .controller('cont', function($scope) {
    //use this to avoid referencing window in the template
    //$scope.Array = Array.prototype;
    $scope.document = {
      "GENERAL_FIELDS": {
        "Source_Type": "custom",
        "Annotations": [
          "216/content/Factiva_CM_001/Proteins",
          "216/content/Factiva_CM_001/Fact"
        ],
        "Content": [
          "   Baculovirus; Budded virus; Ultrastructure; Cryo-EM;"
        ],
        "Title": [
          "Budded baculovirus particle structure revisited"
        ]
      },
      "stn": {
        "Document_Type": [
          "Journal",
          "Article"
        ]
      }
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ang" ng-controller="cont">
  <div id="titsec" class="comdocdet" ng-repeat="(category, group) in document">
    <div ng-repeat="(key, value) in group">
      <div class="pTitle">
        {{key}}
      </div>
      <div class="contdesc">
        <div ng-if="window.Array.isArray(value)">
          <div ng-repeat="v in value">
            {{v}}
          </div>
        </div>
        <div ng-if="!window.Array.isArray(value)">
          {{value}}
        </div>
      </div>
    </div>
  </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

"Is there a way to retrieve "Lorem ipsum" information from a web service in JSON format

Does anyone know of any sample web services that serve JSON data? I'm looking to practice consuming JSON for testing and learning purposes. I would even be interested in downloading JSON files with images and other content to study offline. Perhaps th ...

The ng-class index is malfunctioning

Seeking help with troubleshooting the following code: <div> <table class="list" border="0" cellpadding="0" cellspacing="0"> <thead> <tr class="headerRow"> ...

What are the steps to ensure that data retrieved from an API is accurately displayed in a table?

My current goal is to collect data from the crypto compare API and display it in a table format. Although I am able to generate the necessary elements and append them to the table body, I am facing an unusual issue. Each time I use a for loop to iterate th ...

How to prevent a directory from being copied in webpack within Vue CLI

Currently, I am working on a Vue3 project created using Vue CLI 5.0.1 In my setup, there is a public folder that contains static assets necessary for serving the application. However, this folder is quite heavy, around 1GB in size. Whenever I run the npm ...

Cricket score update features on the client side

Looking for assistance with client-side code development! I am currently working on an Android application using Ionic that involves live cricket scores. I have purchased a cricket API and understand how to connect to it using Node.js on the server side. ...

Send the form to the webpage and display various div elements based on the entered information

I have created a form that is designed to display one of four hidden divs on a page, depending on the input provided. Here is the form: <form> <input id="place" name="place" type="text"> <input name="datepicker" type="text" id="datepicker" ...

Utilizing Angular 2 for Integration of Google Calendar API

I recently attempted to integrate the Google Calendar API with Angular 2 in order to display upcoming events on a web application I am developing. Following the Google Calendar JavaScript quick-start tutorial, I successfully managed to set up the API, inse ...

Exploring ways to display a JavaScript object on click from a .json file

As I delve into the world of javascript and json, I find myself facing a challenge. I am looking to extract information (using the Get Information function) from a json file within a javascript function triggered by an event. The catch is, I want to accom ...

Tips for transferring a value from a view to a controller using AngularJS

I've created a controller that dynamically generates tables based on data retrieved from the backend using $http.get. I'm wondering how I can pass a value to this controller from the view, indicating which URL it should use to fetch the data for ...

Ways to verify if one div in jQuery contains identical text to another div

I need help with a jQuery script to remove duplicate text in div elements Here's the requirement: If div1 contains the text "hi" and div2 also contains "hi", then div2 should be removed Below is my current code snippet: <script src="https:/ ...

Combining Summernote images with Node.js using Express.js

While there are numerous solutions available for handling the Summernote file-upload in PHP, I have struggled to find a satisfactory solution for Node.js. Here is My JavaScript: $(document).ready(function() { // $('#summernote').summernote( ...

Is it possible to save or write a text file in the VueJs renderer process without the need to open the dialog box?

Currently, I am working on a project using VueJs + electron, where I need to save a text file to the user's PC without any prompt or dialog box popping up. I am aware of how to do this using require('fs'), but unfortunately fs does not work ...

Creating and downloading a Word document with Node.js by utilizing officegen

Recently, I've been trying to utilize the officegen npm module in order to generate a word (docx) file and then download it. Previously, I relied on the tempfile module to create a temporary path for the purpose of downloading. Below is the code snipp ...

Tips for preventing a Wistia video from playing in a tab when moving away from the tab

Hey everyone, I'm facing an issue with a jsp page that contains multiple tabs. One of the tabs has a wistia video embedded in it. In Firefox and Chrome, when I switch away from the video tab, the video stops playing as expected. However, in Internet ...

Top button disappears in Chromium browser after fade-in effect

I've encountered a very peculiar issue. Whenever I use the page down or fragmented identifier to jump to a specific div, my "go to top" image disappears. Here is the code snippet: HTML: <a title="Go to top" href="#" class="back-to-top"></ ...

Craft dynamic SVG components using TypeScript

Looking to generate a correctly formatted SVG element using TypeScript: createSVGElement(tag) { return document.createElementNS("http://www.w3.org/2000/svg", tag); } Encountering an issue with tslint: Error message: 'Forbidden http url in str ...

Oops! Material-UI is giving an error because the data grid component needs each row to have a unique id property. There was a row provided in the rows prop that does not have an

I've encountered an error that states: Error: Material-UI: The data grid component requires all rows to have a unique id property. A row was provided without id in the rows prop: Whenever I try to add a new row to the existing rows in the DataGrid co ...

Importing modules dynamically in NextJS allows for the loading of

I have a basic function that is responsible for loading a script: const creditCardScript = ( onReadyCB, onErrorCB, ) => { let script = document.createElement("script"); script.type = "text/javascript"; script.src = process.CREDIT_CARD_SCRIPT; ...

Anchoring links on a webpage that provide users with a clear indication of their current position within the page

In the scenario of a single-page website with various sections (divs) and a header containing links to different anchors on the page, there is a desire to have an indicator highlight which anchor the user is currently viewing. An example of this can be s ...

Learn how to mock $resource in AngularJS using $promise.then in your jasmine tests

I have a factory that utilizes Angular resource to fetch data from an API. I've developed a function called getObjectById within the service, which uses the factory to request a specific object by ID, then adjusts the object before returning it. Serv ...