How can I retrieve a specific key from a nested array while using ng-repeat to iterate through it

I have successfully created a code snippet that retrieves JSON data and displays it in HTML using AngularJS.

<div class="activity" ng-app="stream" ng-controller="streamCtrl">
        <ul ng-repeat="x in myData">
            <p class="author"><a href="https://hypothes.is/stream?q=user:{{x.user}}">{{x.user}}</a></p>
            <p class="context_title"><a class="context" href="{{x.links.incontext}}">{{x.document.title}}</a></p>
            <p class="exact">{{x.target[0].selector.find(selector => selector.exact).exact}}</p>
            <p class="text" btf-markdown="x.text">{{x.text}}</p>
            <span ng-click="loadFromMenu($parent.$index)" ng-repeat="y in x.tags">
                <a href="https://hypothes.is/stream?q=tag:{{y}}">[{{y}}]</a>
            </span>
            <p class="reply"><a href="{{x.links.incontext}}">reply</a></p>
            <br>
        </ul>
    

While everything is functioning correctly, I've noticed that the location of the key "exact" within the "selector" array can vary. Some API responses place it in the third subarray, while others place it in the fourth.

For example, in this specific JSON segment, "exact" is located in the third subarray within the selector:

{
    "total": 9,
    "rows":
    [
        {
            "updated": "2016-07-19T20:46:47.509685+00:00",
            "group": "__world__",
            "target":
            [
                {
                    "source": "http://...",
                    "selector":
                    [
                        {
                            "endContainer": "/div[3]/div[1]/div[1]/section[1]/div[1]/p[98]",
                            "startContainer": "/div[3]/div[1]/div[1]/section[1]/div[1]/p[97]/b[1]",
                            "type": "RangeSelector",
                            "startOffset": 0,
                            "endOffset": 0
                        },
                        {
                            "type": "TextPositionSelector",
                            "end": 22803,
                            "start": 22676
                        },
                        {
                            "exact": "Are ...",
                            "prefix": "esearch...",
                            "type": "TextQuoteSelector",
                            "suffix": "List of References Berkeley,"
                        }
                    ]
                }
            ],
            "links":
            {
                "json": "https://..",
                "html": "https://..",
                "incontext": "https://.."
            },
            "tags":
            [
                "a",
                "b"
            ],
            "text": "They ..",
            ...
    ]}

My concern is ensuring that Angular always accesses the "exact" property regardless of its position within the "selector" arrays. What would be the most effective approach to achieve this?

Answer №1

If my understanding is correct, you are only interested in the selector x.target[0] that contains the keyword exact.

To achieve this, filtering the selectors based on that specific requirement will solve the problem:

<!-- Edit: there was a suggested solution here that did not parse correctly. Refer below for the corrected version. -->

Keep in mind that .filter() returns a list of all matching elements, so you need to choose one result (the [0]) yourself.

Furthermore, I have provided an ES5 example for simplicity. However, with ES2015 features like .find() and the concept of 'truthy' values, you can refine it as follows:

<p class="exact">{{ x.target[0].selector.find(x => x.exact).exact }}</p>

Edit: It appears that using a { symbol within a template expression causes parsing issues.

To workaround this, move the filter predicate to the $scope:

// inside the controller
$scope.hasExactProperty = function(selector) {
  return selector.exact !== undefined;
};
<!-- within the template -->
<p class="exact">{{ x.target[0].selector.filter(hasExactProperty)[0].exact }}</p>

Alternatively, transfer the entire processing of x to the $scope (similar to Rajesh's answer):

// inside the controller
$scope.getExact = function(x) {
  return x.target[0].selector.filter(function(x) {
    return x.exact !== undefined;
  })[0].exact;
};
<p class="exact">{{ getExact(x) }}</p>

Note that if you utilize the controller via controllerAs, you must assign this.hasExactProperty/this.getExact.

Answer №2

To retrieve the value of exact, a function can be created to loop through all selectors in the object.

var o = {
  "target": [{
    "source": "http://...",
    "selector": [{
      "endContainer": "/div[3]/div[1]/div[1]/section[1]/div[1]/p[91]/b[1]",
      "startContainer": "/div[3]/div[1]/div[1]/section[1]/div[1]/p[91]/b[1]",
      "type": "RangeSelector",
      "startOffset": 0,
      "endOffset": 266
    }, {
      "type": "TextPositionSelector",
      "end": 22559,
      "start": 22293
    }, {
      "exact": "If we consider ...",
      "prefix": " blablah. Someone:",
      "type": "TextQuoteSelector",
      "suffix": "Someone2: In filmmaking as researc"
    }]
  }]
}

function getValueInObj(obj, key) {
  return obj.target[0].selector.find(function(_o) {
    return _o[key];
  })[key];
}

console.log(getValueInObj(o, "exact"));

In order to use this function, you will need to pass the current object as an argument:

<p class="exact">{{getValueInObj(x)}}</p>

Please note that only the first value of exact is considered in this implementation. Additionally, Array.find may not be supported by IE. To achieve compatibility, consider using a polyfill or try using Array.filter.

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

The value of Yargs.argv is consistently displayed as [object Object]

In my Ubuntu 16.04 environment, I enrolled in a node.js course on Udemy. Following the instructor's guidance, I initially used the exact version mentioned and later updated to the latest version (11.0.0). Surprisingly, both versions yielded the same o ...

retrieve information from various components identified by the common class name by employing ajax requests

I have a component labeled with the class tclick indicating a sample class <label class="btn btn-default tclick" data-tloc="value1" data-tkey="key1" > <label class="btn btn-default tclick" data-tloc="value2" data-tkey="key2" > <label class= ...

Issue with displaying AngularJS option values in select box on Windows tablet with IE browser

Everything is working perfectly fine with binding the data in the select box input option field across all browsers and operating systems, except for Windows Tablet. Has anyone encountered this issue before? Does anyone have any insights on why it might n ...

What could be causing the appearance of a Firefox error message during the execution of a Protractor test?

Currently, I am conducting end-to-end testing on an AngularJS application using Protractor. Every time I execute a spec, Firefox launches and closes with a particular message appearing: After that, Firefox starts working properly and the specs run smooth ...

The ng-click function seems to be malfunctioning within the Angular JS framework

Whenever a list element is clicked, I want to change the scope value and also trigger an onclick function. However, in this particular code, ng-click is not functioning when we add a label for the list element. Here is the code snippet: <ul class="" ...

Unable to use console log in shorthand arrow function while working with Typescript

When debugging an arrow function in JavaScript, you can write it like this: const sum = (a, b) => console.log(a, b) || a + b; This code will first log a and b to the console and then return the actual result of the function. However, when using TypeSc ...

Troubleshooting hidden form field functionality in AngularJs

In my Laravel application, I have an HTML form with hidden fields. These hidden values need to be sent to the AngularJS controller. <form accept-charset="UTF-8" enctype="multipart/form-data"> <input name="_token" type="hidden" value="{{ csrf ...

Displaying Component when Clicked using Vue.js

How can I display a modal component after an "on click" event? Is it possible to show a component using a method call, or what is the recommended approach in this scenario? Here is my specific use case: I have multiple cards each containing various infor ...

Get rid of the seconds in the output of the toLocaleTimeString

The method Date.prototype.toLocaleTimeString() provides a language-sensitive representation of the time part of a date in modern browsers. Unfortunately, this native function does not offer an option to exclude the display of seconds. By default, it shows ...

How to dynamically populate a Vue multiple select dropdown with v-for loop?

I have been attempting to implement multi-select questions in Vue using v-for. The Select menu and its options are populated via JSON data. Unfortunately, I am facing difficulty in retrieving the selected results as expected. Whenever I select an option ...

When utilizing backend Node.js with MongoDB, the patch request is unable to successfully update date type values

Using node.js, I have created the backend and integrated MongoDB for data persistence. However, I am facing an issue where I am unable to update the field of date type when making a patch request. Below is the code snippet for handling patch requests in t ...

Utilize jQuery Function on Identical Class of <ul> Elements

I have integrated a listview control in my ASPX page. The data is being fetched from the database and displayed in the listview. I have also utilized jQuery script to implement the .fadein() and .fadeout() effects on the listview elements. However, when I ...

What is the url of the file at input.files[i]?

I've encountered an issue with my JavaScript code. Currently, when a user uploads a file, the code grabs the file name. However, I need it to fetch the file's URL on the user's PC instead. How can I implement this? This is my code snippet: ...

Utilizing WCF as a conduit or enveloper: how does it work?

Looking for advice on a unique service I have developed that provides constant updates from the field 24/7. The service utilizes a push mechanism and requires a proprietary client to receive these updates. Although unsure if this is the best approach, I ha ...

What a great method to execute a button click within the same button click using jQuery!

Here's an example of code that attempts to make an ajax call when a user clicks a button. If the ajax call fails, the button should be reclicked. I've tried this code below, but it doesn't seem to work. $("#click_me").click(function(){ ...

The navigation bar remains fixed while the section heading fails to display properly

================================= My webpage acts like a homepage on the web. The issue arises when clicking on a new link, as my navbar is fixed and covers the section heading. I need the page to display the section heading properly even after clicking o ...

Is there a way for me to determine if something is hidden?

My goal is to have selector B toggle when selector A is clicked or when clicking outside of selector B. This part is working fine. However, I'm struggling with preventing selector B from toggling back unless selector A is specifically clicked - not w ...

"When an item is removed from ng-repeat in AngularJS UI Bootstrap popover, the outside click trigger will automatically close the

Utilizing the AngularJS UI Bootstrap popover with an outside click trigger and a custom template has been successful, except for one issue. I have implemented an ng-repeat within my template that allows users to remove items from the list. However, when an ...

Iterate through a local storage object using JavaScript's looping mechanism

I am currently working on a project to create a shopping cart using local storage. I have initialized the local storage with the following code: var cart = {}; cart.products = []; localStorage.setItem('cart', JSON.stringify(cart)); I then use ...

An individual in a chat App's UserList experiencing issues with incorrect CSS values. Utilizing Jquery and socketio to troubleshoot the problem

Currently, I am testing a new feature in a chat application that includes displaying a user list for those who have joined the chat. The challenge is to change the color of a specific user's name on the list when they get disconnected or leave the cha ...