Obtain the key's name from the select query

My task is to populate a select element from JSON data, but the challenge lies in the formatting of the JSON where the keys contain important information. I do not have control over how the data is structured.

I am attempting to iterate through the JSON and extract the key names for the main objects within the array. However, due to it being an object, I am unable to simply retrieve its name - Object.keys() does not work as expected within ng-options due to scoping issues.

I have tried various approaches similar to the following code snippet without success:

<select ng-model="$ctrl.vals"
        ng-options="val as key for (key, val) in $ctrl.data"
        ng-change="$ctrl.onChange()" name="{{$ctrl.name}}"
        size="{{$ctrl.data.length}}" multiple>
</select>

The above code returns "0" because it is formatted as 0: [object object]. The closest result I achieved was getting [Object Object] returned, but my goal is to retrieve the key of that object, which has proven challenging.

An example of the data format I'm dealing with is:

{
"Games": [{
    "Name": "Warhammer 40k 8th Edition",
    "Factions": [{
        "Space Marines": {
            "Units": [{
                "Name": "Primaris Space Marine Captain",
                "Number": 1,
                "Cost": -1,
                "Ability": "When captain enters play you win",
                "AddOns": [{
                    "Name": "My AddOn",
                    "Cost": 0,
                    "Text": "Add an extra Captain",
                    "IsSelected": false
                }],
                "Gear": [{
                    "Name": "Frag Grenade",
                    "Cost": 0
                }]

            }]
        }
        }]
    }]
}

Within the given JSON context above, my objective is to include Factions and display the text "Space Marines" as an option. What could I be overlooking?

Answer №1

If the reference to $ctrl.data in your code pertains to the value of the "Factions" property, then the ng-options syntax you are using is not suitable (specifically, the ... for (key, value) in ... structure necessitates $ctrl.data to be an object, which it is not).

Therefore, it would be advisable to utilize the array format for ng-options, allowing you to include extra functions that can extract the label and model associated with a selected option.

Here is a possible implementation:

angular
  .module('app', [])
  .controller('ctrl', function () {
    const $ctrl = this;
    $ctrl.modelFor = function (obj) {
      const [key] = Object.keys(obj);
      return key ? obj[key] : null;
    };
    $ctrl.labelFor = function (obj) {
      const [key] = Object.keys(obj);
      return key;
    };
    $ctrl.data = [{
      "Space Marines": {
        "Units": [{
          "Name": "Primaris Space Marine Captain",
          "Number": 1,
          "Cost": -1,
          "Ability": "When captain enters play you win",
          "AddOns": [{
            "Name": "My AddOn",
            "Cost": 0,
            "Text": "Add an extra Captain",
            "IsSelected": false
          }],
          "Gear": [{
            "Name": "Frag Grenade",
            "Cost": 0
          }]
        }]
      }
    }];
  });
<div
  ng-app="app"
  ng-controller="ctrl as $ctrl">
  <select
    ng-model="$ctrl.vals"
    ng-options="$ctrl.modelFor(obj) as $ctrl.labelFor(obj) for obj in $ctrl.data"></select>
  <pre>{{ $ctrl.vals }}</pre>
</div>
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e2838c85978e8390a2d3ccd5ccda">[email protected]</a>/angular.min.js"></script>

Additionally, it appears that your data structure may need some revision. If each element within $ctrl.data can contain multiple keys, note that this method will pick just the first one arbitrarily (therefore, the order is not guaranteed when iterating through keys).

Answer №2

Modify the information:

 $ctrl.mapped = $ctrl.data.map(_ => {
     var entry = Object.entries(_)[0];
     return { key: entry[0], value: entry[1] };
 });

Implement it in the HTML structure:

<select ng-model="$ctrl.vals"
        ng-options="item.value as item.key for item in $ctrl.mapped"
        ng-change="$ctrl.onChange()" name="{{$ctrl.name}}"
        size="{{$ctrl.data.length}}" multiple>
</select>

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

Guide on sending a JSONP POST request using jQuery and setting the contentType

I'm struggling to figure out how to make a jsonp POST request with the correct content type of 'application/json'. Initially, I was able to send the POST request to the server using the jQuery.ajax method: jQuery.ajax({ type: ...

Is there a new update to Google Maps API?

After successfully building a map component for a web application using google maps, open layers, and the dojo toolkit, it suddenly stopped loading earlier this morning. Even though there are no JavaScript errors and open layers and Google still initialize ...

Converting Blob to Base64 using javascript

I've managed to successfully convert my base64 (DATA_URI) image into a blob, but I'm facing issues with reverting it back. Here's what my base64 to blob code looks like for better understanding. Check out this link. b64toBlob(b64Data, cont ...

Integrate Thymeleaf properties seamlessly into JavaScript code

I am attempting to embed a property from Spring's application.properties into JavaScript. It is working properly with the following code: <h1 th:utext="${@environment.getProperty('key')}"></h1> However, it returns null with th ...

Converting Database Information to JSON Format for Mobile Authentication Form

Currently, I am working on a Mobile App project using Phonegap that requires users to log in before retrieving JSON data. This PHP page is responsible for connecting to the mobile site and fetching the necessary information. <?php $con = mysqli_connec ...

What is the best way to choose the current Div's ID, as well as its Width and Height properties?

Within this section, there are four div elements with varying widths, heights, and colors that appear and disappear when their respective buttons are clicked. I am adding an "activeDiv" class to the visible div in order to easily select it using that class ...

What is the process for registering a click using a class in jQuery and retrieving the ID of the clicked element?

Currently, I am working on developing a webpage where I need to use jQuery to register a click using the items class and then extract the ID of that particular object. For example: HTML: <div class="exampleclass" id="exampleid1"></div> <d ...

Is there a way to display a foundation.css drop-down menu using jQuery?

After attempting to create a navigation bar using foundation.css, I encountered an issue where the sub-menu does not appear when hovering over it with the mouse. The main question at hand is how to display the sub-menu of test on this specific webpage. D ...

By default, apply the active class to the initial element in the list and update the active class upon clicking in Next.js

As a newcomer to React, I am struggling with setting the active class in my CSS file. I have two classes, btn and active. My goal is to assign the active class to the first button by default and then switch it to the currently clicked button when interacti ...

What is the best way to apply a class for styling my JavaScript code in CSS? I'm having trouble getting classList

I am having trouble adding a class to my JavaScript script in order to animate the images created in JavaScript to fall off the page. I have tried using the code element.classList.add("mystyle");, but every time I insert it, my JavaScript stops working. T ...

Navigating through child elements within a div using JavaScript

I recently coded a div using this snippet... let sidebarBox = document.createElement("div"); sidebarBox.id = "sidebarBox"; ...and then I created a second div like so... let sidebarAd = document.createElement("div"); sidebarAd.className = "sidebarAd"; B ...

Run the setInterval function immediately on the first iteration without any delay

Is there a way to display the value immediately the first time? I want to retrieve the value without delay on the first load and then refresh it in the background. <script> function ajax() { ...

Is it possible to consolidate React and React-DOM into a unified library instead of having them separate?

Is it possible to combine React.JS and React-DOM.JS into a single library? In all the web applications I've encountered, we always have to import both libraries separately. Have there been any cases where either of these libraries can be used on its ...

Is it possible to access the ID element of HTML using a variable in jQuery?

I have fetched some data from a JSON ARRAY. These values include Value1,Value2, and Value3. Additionally, I have an HTML checkbox with an ID matching the values in the array. My goal is to automatically select the checkbox that corresponds to the value re ...

What is the best way to convert a 2D PHP array into a JavaScript array?

I have encountered a problem with a PHP array setup as follows: $output = array(array(1,1,1,1),array(2,2,2,2),array(3,3,3,3)); When I encoded the array to JSON, I received this output: $output = {"1":[1,1,1,1],"2":[2,2,2,2],"3":[3,3,3,3]} My goal is to ...

Preloading videos for optimal performance on mobile devices

Looking for a solution where 4 MP4/video files, each 5MB in size, can be played consecutively without gaps between them on all browsers and devices. Preferably not looking for a solution involving the replacement of video source files. The current approac ...

Utilizing Google Maps API to automatically set an address on page load

As a beginner in using the Google Maps API, I have successfully integrated a Google Map into my project. However, I am struggling to figure out how to set specific addresses on the map. I have a list of 2,000 entries in a database, each including an addres ...

CSS Switchable Style Feature

I am in need of some assistance with the navigation on my website. You can find the current code at this link: http://jsfiddle.net/Sharon_J/cf2bm0vs/ Currently, when you click on the 'Plus' sign, the submenus under that category are displayed bu ...

The Twitch API is providing inaccurate channel information

Currently facing an issue while working with the Twitch API. When making a GET request to /api.twitch.tv/helix/search/channels?query=[STREAMER_NAME], it seems to be returning the wrong streamer/user. For instance: /api.twitch.tv/helix/search/channels?quer ...

What is the best way to display changing session variables in PHP?

Purchase Page: This page allows customers to select business card orders in various foreign languages and customize their options. Whenever a user decides to add an extra card by clicking a button, javaScript dynamically includes new form fields. To ensur ...