Link the <select> element with ng-options and ng-model, ensuring that the model contains a composite key

I am facing a challenge with my Angular service that retrieves a list of objects with a composite key comprising two parts. I am struggling to write the bindings in a way that properly re-binds existing data. Below is my current attempt:

angular.module("app", [])
  .controller("fooCtrl", function() {
    // Data obtained from Angular service / back-end:
    this.options = [
      { part1: 3, part2: 101, displayName: "Option 3-101" },
      { part1: 4, part2: 651, displayName: "Option 4-651" },
      { part1: 4, part2: 999, displayName: "Option 4-999" }
    ];

    this.item = { selectedOption: { part1: 4, part2: 651 } };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>

<div ng-app="app" ng-controller="fooCtrl as vm">
  <select ng-options="option.displayName for option in vm.options track by part1 + '-' + part2"
          ng-model="vm.item.selectedOption"></select>
  <hr>
  Debug info:
  <pre>{{vm.item | json}}</pre>
</div>

However, the above setup is not functioning as expected: it should be selecting "Option 4-651" upon loading, but it fails to do so.

Please note that the client-side displayName field is added to the options, but it does not exist in the selectedOption during initialization. I am open to modifying the selectedOption to include the displayName property without affecting the back-end processing since the server-side DTO does not have a displayName property.

Crucially, I am seeking a solution without altering the loading process in the JavaScript or changing the structure of options and selectedOption. Specifically:

  • I understand I could manually reset this.item using logic at the end of the controller method to reference the actual entry in options, though this is complicated in real-time scenarios due to asynchronous loading.
  • I also acknowledge that I could modify both the selectedOption and individual options to incorporate a "composite key" as a "single compound key," like part1and2: "3-101", yet this would require addressing the underlying issue rather than directly binding the UI to DTOs from the back-end.

Is there an elegant way to tackle this using a track by expression in the binding expressions? Alternatively, must I resolve this matter within the controller or service code?

Answer №1

To enhance your JavaScript object binding process, consider restructuring the object to include a new property like part12. This will allow you to easily track and manage the data more efficiently.

Answer №2

If the JSON response includes the displayName, it should also be added to the selectedOption when setting the option in the controller.

Here is an example of how you can achieve this:

angular.module("app", [])
  .controller("fooCtrl", function() {
    // Data from Angular service / back-end:
    this.options = [
      { part1: 3, part2: 101, displayName: "Option 3-101" },
      { part1: 4, part2: 651, displayName: "Option 4-651" },
      { part1: 4, part2: 999, displayName: "Option 4-999" }
    ];

    this.item = { selectedOption: { part1: 4, part2: 651} };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>

<div ng-app="app" ng-controller="fooCtrl as vm">
  <select ng-options="option as ('Option ' + option.part1 + '-' + option.part2) for option in vm.options track by (option.part1 +'-'+ option.part2)"
          ng-model="vm.item.selectedOption"></select>
  <hr>
  Debug info:
  <pre>{{vm.item | json}}</pre>
</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

Angular dropdown tooltip for overflowing text

Here is the select element in question: <select id="select-full" title="Make selection" class="form-control form-custom input-sm" name="Select" ng-model="form.select" ng-options="select.displayName as select.text for select in selec ...

A guide to testing a controller by simulating a service using jasmine

I'm currently in the process of testing an Angular controller by mocking the calls made to a factory using Jasmine. Below is my controller setup: (function () { 'use strict'; function initScoresController(scoresFactory){ var vm = t ...

Is placing JavaScript on the lowest layer the best approach?

I'm facing a unique situation that I haven't encountered before and am unsure of how to address it. My website has a fixed top header and footer. On the left side, there is a Google Adsense ad in JavaScript. When scrolling down, the top header s ...

What is the best way to create a tree structure that can hold data from multiple sources?

I have a variety of Models within my application: ModelA: fields: [id, name], hasMany: ModelB ModelB: fields: [id, name, attr], hasMany: ModelC ModelC: fields: [id, name, attr] To efficiently manage this nested data, I utilize a data store in conjuncti ...

Images do not appear on Bootstrap Carousel as expected

I am facing an issue where the images are not displaying on my bootstrap carousel or when I try to display them individually using their class. I am utilizing bootstrap and express for my project. I have verified multiple times that the file path to the im ...

Utilizing form inputs for uploading images in Ionic framework

I have a platform wherein users can fill out a form and upload a single image before finalizing their submission. Now, I am attempting to replicate the same functionality using the Ionic framework. Here's my progress thus far: 1. Installed ngCordov ...

Any tips on making Angular 8's sort table function seamlessly integrate with data retrieved from Firebase?

I am currently working on an angular PWA project that utilizes a material table to display data from Firebase. The data is being shown properly and the paginator is functioning as expected. However, I am facing an issue with sorting the data using mat-sort ...

Embedded URL in dynamically created AJAX text

I created a search field that uses ajax/jquery to generate a list of users. Result: <li class="list-group-item"> <span class="glyphicon glyphicon-user"></span> <span class="badge addUserToGroup" data-user="{{ user.getId }}"&g ...

changing the vertical position of an element using JavaScript

I'm currently working on a project where I have a canvas that animates upwards when a button is clicked. However, I'm facing an issue with making it go back down after the animation completes. It seems to be getting stuck and not returning to its ...

Attempting to connect information to state using an input field that is being iterated over in React

Struggling with binding state values to input values using an onChange function handleChange = event => { this.setState({ [event.target.name]: event.target.value }); }; The issue arises when the Input fields are within a map and assi ...

angularjs dynamically display expression based on controller value

I'm not the best at explaining things, so I hope you all can understand my needs and provide some assistance here. Below is a view using ng-repeat: <div ng-repeat="item in allitems"> {{displaydata}} </div> In my controller, I have the f ...

Matching a regular expression pattern at the beginning of a line for grouping strings

One of my tasks involves working with a markdown string that looks like this: var str = " # Title here Some body of text ## A subtitle ##There may be no space after the title hashtags Another body of text with a Twitter #hashtag in it"; My goal ...

Error Occurred: ngRepeat directive encountered an invalid expression while attempting to render the

HTML <tr ng-repeat="sale as examples"> <td class="text-right"> @{{sale.sales_person}}</td> <td class="text-right"> @{{sale.sales_total}}</td> <td class="text-right"> @{{sale.sales_target_amount}}</td> ...

JSF CommandLink malfunctions on Firefox when reRendering an entire form

I am currently working on a JSF 1.2 application (Sun RI, Facelets, Richfaces) that was previously designed only for IE6 browsers. However, we now need to extend our support to include Firefox as well. On one of the pages, there is a form with a button tha ...

Tips for effortlessly moving content by dragging and dropping it into a text box

Before attempting to create something, I want to verify its feasibility. Begin with a text area that can be pre-filled with text and allow users to add or delete text. Alongside the text area, there are small elements that can be images or HTML components ...

Acquiring the asset within the controller

Having trouble accessing my service within the controller. This project was generated with the latest yeoman which handles template creation and file merging during build. Whenever I make changes, Angular stops working without displaying any errors in the ...

Utilizing Angular to fetch data via CORS from a Django Rest Framework backend with authorization restrictions

I am currently working on an Angular application that is consuming a CORS-enabled REST API (Django Rest Framework). I am trying to retrieve all users from http://127.0.0.1/api/users. When accessing the data, I have encountered an issue when the Django view ...

What is the method for determining the number of unique tags on a webpage using JavaScript?

Does anyone have a method for determining the number of unique tags present on a page? For example, counting html, body, div, td as separate tags would result in a total of 4 unique tags. ...

Encountered an error while attempting to load resource: the server returned a 404 (Not Found) status code when trying to load an image in an

I am looking to dynamically load an image when it is selected from a file picker dialog. The code provided below attempts to achieve this, however, the image does not load into the img tag. <script src="https://cdnjs.cloudflare.com/ajax/libs/jq ...

Unable to extract a particular value from a JSON data structure

This situation has been on my mind for a good couple of hours now. I have this json object with example values like so: { "events": [ { "id": 64714, "live": false, "start": "1399117500", "league_ ...