Troubleshooting issues with ng-options not correctly updating ng-model in AngularJS when using ajax requests

I have a question regarding my logic that I can't seem to figure out.

In this Fiddle example, everything works fine without using AJAX or a timeout. However, when I try to implement the same logic with a timeout/ajax, the expected behavior does not occur. Can someone help me understand and fix this issue?

Here is the sample code I am referring to: JS FIDDLE Example

HTML:

<body data-ng-app="appMain">
    <div ng-controller="SearchController">
        <input type="text" ng-model="SearchTerm" />
        <input type="button" value="Submit Search" ng-click="QuerySuggestions()" />
        <select ng-show="ShowSuggestion" name="cmbSelectedSuggestion" ng-model="SelectedSuggestion" ng-options="text as suggestion.Detail for suggestion in SuggestionList" ng-change="WhoIsSelected(suggestion)">
        </select>
    </div>
</body>

AngularJS:

angular.module('appMain',[])
.controller('SearchController',function($scope, $http, $timeout){
  $scope.SearchTerm = '';
  $scope.ShowSuggestion = false;
  $scope.SuggestionList = [];
  $scope.SelectedSuggestion = null;
  $scope.QuerySuggestions = function()
  {
    //Simulating an AJAX request with a 2s delay for response
    $timeout(function(){
      var oJSON = {"List": [
              {
                  "Id": 1,
                  "Type": "State",
                  "Name": "Rio de Janeiro",
                  "Detail": "Rio de Janeiro - State, Brazil"
              }
              ,
              {
                  "Id": 1,
                  "Type": "City",
                  "Name": "Rio de Janeiro",
                  "Detail": "Rio de Janeiro - City, Rio de Janeiro, Brazil"
              }]};

        $scope.SuggestionList = oJSON.List
        $scope.ShowSuggestion = true;
    }, 2000);

  }

  $scope.WhoIsSelected = function($option){
    $scope.WhoIsSelectedFirstApproach();
    $scope.WhoIsSelectedSecondApproach($option);
  }

  $scope.WhoIsSelectedFirstApproach = function(){
    console.log($scope.SelectedSuggestion); //why undefined ?!?!?
  }

  $scope.WhoIsSelectedSecondApproach = function($option){
    console.log($option) //why undefined ?!?!?
  }
})

Answer №1

Remember to always write your ng-options as suggestion.Detail as text, not as text as suggestion.Detail.

Answer №2

After conducting a more thorough search, I was able to successfully resolve the issue and gain a better understanding of my mistakes.

Initially, coming from a T-SQL background, I mistakenly believed that "text" served as an alias for the suggestion.Detail field in the expression

text as suggestion.Detail for suggestion in SuggestionList
. However, this assumption was incorrect. In reality, "text" does not function as an alias; it represents the object or object.field that AngularJS should expose as the ng-model. Therefore, to address this misunderstanding, I needed to update the expression to:
suggestion as suggestion.Detail for suggestion in SuggestionList

ng-options="suggestion as suggestion.Detail for suggestion in SuggestionList"

This adjustment successfully resolved the WhoIsSelectedFirstApproach. Yet, when attempting to pass the object to a function within the ng-change directive, using suggestion in the expression proved ineffective. Recognizing the discrepancy in logic between different ng-* directives, I found a solution by referencing the ng-model field within the ng-change attribute. By adjusting Function(suggestion) to Function(modelField), I effectively addressed this issue:

ng-change="WhoIsSelected(SelectedSuggestion)"

For further details and clarification, please refer to the SOLVED JS FIDDLE

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

Receiving a k6 response that includes a JSON object with a lengthy integer value

During a performance test, I encountered an issue where the response contained items like: {"item":{"id":2733382000000000049}} When parsed using k6's response.json(), it appeared as : {"item":{"id":273338200000 ...

I am attempting to input the form data, but all I see on the console is "null" being printed

I am facing an issue where the console.log(data) statement is printing null on the console. I am trying to send the form data (with id "myform") to a Java backend post method, but for some reason the code is not functioning correctly. Can anyone identify ...

Using Kendo Grid to Transfer Data Between Grid Cells

Recently, I encountered a problem in my Kendo MVC project where I needed to drag a product code from one Kendo Grid to another when the cell value was empty. Here's the scenario: Grid A contains products ordered, but the vendor sending the list has i ...

Can you retrieve the second value using JSON.stringify?

Currently implementing JSON.stringify(data.message) which returns the following value: [ { "code":"PasswordTooShort", "description":"Passwords must be at least 6 characters." } ] I aim to extract the description value for my alert message ...

Displaying the loading image only on the first result within a while loop

When a submit button is clicked on any result, the loading image below the button displays only for the first result in the while loop. For example, if I click the submit button on the first result, the loading image shows below it. However, when I click t ...

Stop the change event from occurring on a textarea when the user clicks on an external cancel button

In a particular scenario, there is a textarea with an autosave feature triggered by the change event. When the textarea is focused on, Save and Cancel buttons appear at the bottom, providing users with options in case they prefer not to simply click outsid ...

Is the JQuery ajax xhr fully completed before it begins?

Having a long script that can take a few minutes to execute, I decided to create a progress bar to display the current state. However, I encountered a problem where xhr evt.loaded/evt.total (30/30) returns 1 (100%) before the long script starts executing. ...

DANGEROUS EVALUATION: Tips for Safe Replacement

Looking for a safer alternative to the code below which utilizes eval. The script creates pop-up windows based on different classes. /* exported popup_default , popup_help , popup_sitemap , popup_footerlinks */ var matchClass = ['popup_default' ...

The performance of Three.js significantly decreases when utilizing onMouseMove in conjunction with RayCaster

I am currently working on an application using three.js, but I am encountering serious performance issues. This particular part of the application is inspired by the Voxel Painter example. In my version, the user initiates placement by clicking on a cell, ...

Transfer information through the react-native-ble-plx module

To initiate a project involving connected devices, I must establish a Bluetooth connection among the different devices. The objective is to develop an application using React Native and then transmit data from this application to my Raspberry Pi. The Rasp ...

What is the best way to transfer data between controllers in my particular situation?

Currently, I am working on developing a factory for the restful services. The main challenge I'm facing is how to transfer data from one controller to another in AngularJS. Specifically, I need to use the data obtained from the first service call to ...

Gliding along a div and concealing it out of view, making it seem like it has disappeared

I attempted to slide down the ".preloader" div after a 2-second delay using JQUERY, but I couldn't get it to work as expected. I didn't want to use a toggle button for this effect. I also experimented with creating an animation using @keyframes, ...

Discover the power of the LIKE clause in MySQL for advanced search capabilities

Struggling to modify a MySQL query to use a LIKE clause and running into errors. $query = "SELECT id,name FROM `hin` WHERE name = '".$q."'"; I've attempted different variations like the following. $query = "SELECT id,name FROM `hin` WHERE ...

Tips for populating an array with boolean values when a checkbox change event occurs:

I am looking to fill the answers array with boolean values. The checkboxes on my form are generated dynamically, but there will only be four of them. When a checkbox is unchecked, its corresponding value in the answers array should be false; when checked, ...

I am trying to showcase a collection of images on my homepage, but unfortunately, it is not functioning as expected

Does anyone know how to display images using Angular? I am currently utilizing the pic controller in an AngularJS file. Any assistance would be greatly appreciated. HTML CODE <!DOCTYPE html> <html> <head> <meta charset="utf-8"& ...

How can items be categorized by their color, size, and design?

[{ boxNoFrom: 1, boxs: [{…}], color: "ESPRESSO", size: "2X", style: "ZIP UP" { boxNoFrom: 13, boxs: [{…}], color: "ESPRESSO", size: "2X", style: "ZIP UP" }, { boxNoFrom: ...

Can you identify the mistake in the XML response?

I encountered an issue with my PHP code (getRout.php) which is meant to respond in XML format. The error message I received was: XML Parsing Error: no element found Location: http://127.0.0.1/direction2/getRout.php Line Number 1, Column 1: edit To view ...

The response from Laravel AJAX is empty

After adding the following code: <meta name="csrf-token" content="{{ csrf_token() }}"> In the ajax section: $.ajax({ url: '{{ route('fav.add') }}', headers: { 'X-CSRF-TOKEN': $(&apo ...

Issue with Sequential Drop Down List Functionality in ASP.Net MVC View Page

I am currently in the process of migrating code from one project to another. Although the code works fine in the original project, it is not functioning properly in the new one. I’m uncertain if something was overlooked on my end. Within this code, ther ...

Designing an interactive header interface using React and Material UI

My header.jsx file contains the following code: // Default Import Statements var Login = require(login.jsx) const HeaderComponent = React.createClass({ getInitialState () { return { loggedIn: false, }; }, render() { return ( ...