The initial attempt to read the JSON file was unsuccessful

Let's simplify it. I have two dropdown menus. Once a user selects a category from the first dropdown, another dropdown menu with subcategories should appear.

However, there seems to be an issue as the subcategory dropdown is always empty.

The JSON data for categories (vm.categories):

[  
   {  
      "doctype":"1120",
      "description":"bla bla",
      "subcategories":[  
         {  
            "@id":1,
            "subcategory":"1",
            "description":"New Offer",
            "templates":[  
               {  
                  "template":"12",
                  "description":"asfafasga",
                  "deliveryChannels":[  

                  ]
               }
            ]
         },
         {  
            "@id":2,
            "subcategory":"2",
            "description":"New Offer",
            "templates":[  
               {  
                  "template":"1121",
                  "description":"asfag",
                  "deliveryChannels":[  
                     {  
                        "deliveryType":"4",
                        "description":"Test"
                     }
                  ]
               }
            ]
         }
      ]
   }
]

HTML code:

<div class="row">
    <div class="col-sm-12">
        <!-- Categories -->
        <label for="category-select"><b>Category&nbsp;</b></label>
        <select name="category-select" ng-model="vm.selectedCategory" required>
            <option value="" disabled>--- Please select a category ---</option> <!-- not selected / blank option -->
            <option value="{{category}}"
                    ng-repeat="category in vm.categories">
             {{category.description}}
            </option>
        </select>
    </div>
</div>
<div class="row">
    <div class="col-sm-12">
        <!-- Sub Categories -->
        <label ng-show="vm.selectedCategory" for="subcategory-select"><b>Sub-Category&nbsp;</b></label>
        <select name="subcategory-select"
                ng-show="vm.selectedCategory"
                ng-model="vm.selectedSubCategory">
            <option value="" disabled>--- Please select a sub-category ---</option> <!-- not selected / blank option -->
            <option value="{{subCategory}}" 
                    ng-repeat="subCategory in vm.selectedCategory.subcategories">
                {{subCategory.description}}
            </option>
        </select>
    </div>
</div>

Any thoughts on why this issue is occurring? It seems I can't access the subcategories array within the selected category.

EDIT: When I include

<span>{{vm.selectedCategory}}</span>
in the HTML, it displays the JSON data correctly. However, if I use
<span>{{vm.selectedCategory.subcategories}}</span>
, it's returning null.

Another edit: Even

<span>{{vm.selectedCategory.doctype}}</span>
is showing null.

Answer №1

One reason for the issue is that your selected value is being treated as a string rather than an object. To resolve this problem, you have a couple of options:

You can convert the selected string to an object using the ng-change directive on the initial selection and the provided function:

$scope.convert = function(){
    $scope.vm.selectedCategory = angular.fromJson($scope.vm.selectedCategory)
}

Alternatively, you can utilize ng-options like so:

<select name="mySelect" id="mySelect" ng-options="category.description for category in data" ng-model="vm.selectedCategory">
</select>

Check out the demo here!

Answer №2

For the purpose of creating a functional demonstration, I needed to simplify vm.[namedVariables] into basic variables. Please see the code snippet below:

var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
  $scope.selectedCategory = '';

  $scope.categories = [{
    "doctype": "1120",
    "description": "bla bla",
    "subcategories": [{
        "@id": 1,
        "subcategory": "1",
        "description": "New Offer",
        "templates": [{
          "template": "12",
          "description": "asfafasga",
          "deliveryChannels": [

          ]
        }]
      },
      {
        "@id": 2,
        "subcategory": "2",
        "description": "New Offer2",
        "templates": [{
          "template": "1121",
          "description": "asfag",
          "deliveryChannels": [{
            "deliveryType": "4",
            "description": "Test"
          }]
        }]
      }
    ]
  }];

});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">

  <div ng-repeat='item in categories'>
    {{item.description}}
    <div ng-repeat='subC in item.subcategories'>
      {{subC.subcategory}} - {{subC.description}}
    </div>
  </div>

  <hr/>

  <div class="row">
    <div class="col-sm-12">
      <!-- Categories -->
      <label for="category-select"><b>Category&nbsp;</b></label>
      <select name="category-select" ng-model="selectedCategory" required>
        <option value="" disabled>--- Please select a category ---</option>
        <!-- not selected / blank option -->
        <option value="{{category.doctype}}" ng-repeat="category in categories">{{category.description}}</option>
      </select>
    </div>
  </div>
  <div class="row">
    <div class="col-sm-12">
      <!-- Sub Categories -->
      <label ng-show="selectedCategory" for="subcategory-select"><b>Sub-Category&nbsp;</b></label>
     
     <ng-container ng-repeat="item in categories">
     <!--
     <p>(1) {{selectedCategory}} </p>
     <p>(2) {{item.doctype}} </p>
     -->
     <select name="subcategory-select" ng-show="selectedCategory == item.doctype" ng-model="vm.selectedSubCategory">
        <option value="" disabled>--- Please select a sub-category ---</option>
        <!-- not selected / blank option -->
        <option value="{{subCategory}}" ng-repeat="subCategory in item.subcategories">
          {{subCategory.description}}</option>
      </select>
      
      </ng-container>
    </div>
  </div>


</div>

Answer №3

Instead of utilizing the value attribute with interpolation, opt for the ng-value directive:

<div class="row">
    <div class="col-sm-12">
        <!-- Categories -->
        <label for="category-select"><b>Category&nbsp;</b></label>
        <select name="category-select" ng-model="vm.selectedCategory" required>
            <option value="" disabled>--- Please choose a category ---</option> <!-- not selected / blank option -->
            ̶<̶o̶p̶t̶i̶o̶n̶ ̶v̶a̶l̶u̶e̶=̶"̶{̶{̶c̶a̶t̶e̶g̶o̶r̶y̶}̶}̶"̶
            <option ng-value="category"
                    ng-repeat="category in vm.categories">
             {{category.description}}
            </option>
        </select>
    </div>
</div>

The use of double curly brackets for interpolation tries to convert the category value into a string which may not be appropriate for objects.

For detailed guidance, consult AngularJS ng-value Directive API Reference.


When I include

<span>{{vm.selectedCategory}}</span>
, it displays [Object Object] and doesn't show subcategories

Pipe vm.selectedCategory into the json filter like so:

<span>{{ vm.selectedCategory | json }}</span>

This technique converts a JavaScript object into a JSON string for better readability.

The json filter is particularly beneficial for troubleshooting. The binding is automatically transformed into JSON when using the double curly notation.

For further insights, refer to AngularJS json Filter API Reference.

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 data in an HTML table based on user search input using Angular

I am currently working on integrating a JSON file into my project, which will eventually be accessed through an API from a server. Right now, I am pulling data directly from an object. My goal is to build an HTML file that features a table with navigation ...

What is the best way to determine the nearest vertex to a given 3D point?

https://i.sstatic.net/Ooh8W.png Objective: I am aiming to identify the closest vertex to the clicked point. Components Needed: Perspective camera Icosahedron geometry (applied basicmeshmaterial with wireframe) Rotating geometry Raycaster Current Clic ...

Is there a way to send a single POST request to two different external URLs simultaneously?

We recently encountered a limitation with one of our SaaS providers who only allows a single URL to be entered in the webhook field. However, we need this webhook request to be sent to two different analytics services simultaneously. To tackle this issue, ...

Successful execution of asynchronous method in Node.js without any errors

When encountering duplicates in the config, I use the code snippet below: require('./ut/valid').validateFile() }); If a duplicate is found during validation, an error is sent like so: module.exports = { validateFile: function (req) { ... ...

Duplicating a div element using jQuery .load

I am facing an issue where attempting to refresh a div results in the duplication of the div, creating one inside the other. The current setup involves the use of jQuery, Struts2, and the Struts2 jQuery plugin for the view. Current Behavior: <div id=" ...

Having trouble with the speed of multiple jQuery posts?

We have encountered some challenges with calling multiple jQuery posts since switching to our new server. On certain pages, we are making multiple jQuery post requests as shown below: $.ajax({ type: "POST", url: "../files/processed/includes/proce ...

Can data from HTML forms be extracted into an Android app when utilizing webView?

Creating a simple HTML form for collecting user input, which is then displayed in a paragraph using both HTML and JavaScript when a button is clicked. The form takes the user's name through a text box: This is the original HTML code: <!DOCTYPE ht ...

Adding a property to every object within an array using Vue.js: A step-by-step guide

Situation: In my data(), I have an array that receives objects from the backend. When the GET request brings back 6 objects, those objects are updated in the array. Issue: I am aware that vm.$set is necessary to add properties to an object. But how can I ...

Trigger a jQuery event when a particular element has finished loading

Is there a way to globally detect when any element (such as textarea) is displayed on the page in order to perform a specific action? The element could also be added dynamically through an AJAX request. // This code snippet is just an illustration of the ...

Vue.js encounters a null value for "$slots.default()[0].el" when dynamically passing a slot using v-for

Is there a way to access the HTMLElement of a dynamically passed slot when using v-for? I'm having trouble as the element (el) always seems to be empty. app.vue : <template> <div id="app"> <prod> <span> ...

What makes a single numerical value in an array suitable for basic arithmetic operations?

I find it puzzling how an empty array or an array with just one "numerical" value can be used in various calculations. [] * [] === 0 // true [2] * [2] === 4 // true ["2"] * ["2"] === 4 // true Interestingly, not every operator behaves in the same way. ...

The initial line of the HTML canvas features a varying width

Why does the first line on the canvas have a different width than the others? I'm having trouble figuring it out. Can anyone provide some assistance? var x = document.documentElement.clientWidth; var y = document.documentElement.clientHeight; var ...

Tips for automatically inserting a "read more" link once text exceeds a certain character count

Currently utilizing an open-source code to fetch Google reviews, but facing an issue with long reviews. They are messing up the layout of my site. I need to limit the characters displayed for each review and provide an option for users to read the full rev ...

"Bootstrap Toggle malfunctioning when switching between disabled and enabled states on a restricted set of

Having an issue with the Bootstrap Toggle Library in combination with Bootstrap 4. I am trying to restrict users from switching 'ON' more than a set number of elements. Here is the snippet of my HTML code: <div style="border:solid border-widt ...

Error: Unable to Navigate to Present Location ("/search") as It is Duplicated

I keep encountering the error message NavigationDuplicated when I attempt to perform multiple searches. My search function is located in the navbar, and it's configured to capture the input value using a model. Subsequently, this value is passed as a ...

The $.each function seems to be stuck and not cycling through the

Dealing with a rather intricate JSON structure, I'm encountering difficulty iterating through it using the $.each() function. It seems to be related to the unusual 2-dimensional array passed in the value section of the standard array (hopefully that m ...

Add every WebSocket message to a div element in VUE3

Currently, I am facing an issue while attempting to display each trade from Binances Websocket Stream in my VUE3 component. The challenge I'm encountering is that only one line gets rendered and it keeps updating continuously. This is not the desired ...

Animating on page load with delay using Angular JS

Recently, I've been working on animating the logo for my app's home screen. My goal is to have the logo fade in after a 2-second delay and then start a looped animation where it bobs up and down. Initially, I considered adding a timeout function ...

Transform an image into Base64 format by effortlessly dragging and dropping

I am looking to add a specific feature to my website that can be implemented solely on the client side using JavaScript or any JavaScript library. The requirement is to allow users to drag and drop an image from their local machine directly into the brows ...

Break down the execution process of the intricate JavaScript return statement

I am struggling to understand the execution flow of this return statement. If someone could clarify how it works and perhaps discuss the advantages and disadvantages of using such a complex statement instead of a more readable multi-line statement, I wou ...