Knockout.js dropdown pre-selection in nested JavaScript objects is functioning smoothly in KO 2x versions, but there seems to be a compatibility issue with KO 3x versions

This is a sample data that will be loaded from the server in JSON format and constructed into the below object graph. It consists of an array of "Choice" objects, each with properties like id, name, stages, & currentStageId. The "stages" property in the "Choice" object contains an array of "Stage" objects, each with properties like id, name, & value. Each "Choice" object progresses through stages from "First Stage" to "Fourth Stage," allowing users to select a "Stage" from a dropdown list and save it. The "currentStageId" property stores the id of the stage object the respective "Choice" object is currently in.

Note: Different choices can have different types of stages for simplicity.

For Choice 1, the current saved stage is 4.

var data = [
new Choice({
    id: 1,
    name: "One",
    stages: [
    new Stage({
        id: 1,
        name: "First Stage",
        value: 25
    }),
    new Stage({
        id: 2,
        name: "Second Stage",
        value: 50
    }),
    new Stage({
        id: 3,
        name: "Third Stage",
        value: 75
    }),
    new Stage({
        id: 4,
        name: "Fourth Stage",
        value: 100
    })],
    currentStageId: 4

}),
new Choice({
    id: 2,
    name: "Two",
    stages: [
    new Stage({
        id: 1,
        name: "First Stage",
        value: 25
    }),
    new Stage({
        id: 2,
        name: "Second Stage",
        value: 50
    }),
    new Stage({
        id: 3,
        name: "Third Stage",
        value: 75
    }),
    new Stage({
        id: 4,
        name: "Fourth Stage",
        value: 100
    })],
    currentStageId: 3

}),
new Choice({
    id: 3,
    name: "Three",
    stages: [
    new Stage({
        id: 1,
        name: "First Stage",
        value: 25
    }),
    new Stage({
        id: 2,
        name: "Second Stage",
        value: 50
    }),
    new Stage({
        id: 3,
        name: "Third Stage",
        value: 75
    }),
    new Stage({
        id: 4,
        name: "Fourth Stage",
        value: 100
    })],
    currentStageId: 2

})];

The following are the "Choice" & "Stage" models for holding data and ViewModel for binding:

function ViewModel(data) {
    var self = this;
    self.choices = ko.observableArray(data);
    self.selectedChoice = ko.observable();
}

function Choice(data) {
    this.id = data.id;
    this.name = data.name;
    this.selectedStage = ko.observable(ko.utils.arrayFirst(data.stages, function (item) {
        return item.id === data.currentStageId;
    }));
    this.stages = ko.observableArray(data.stages);

}

function Stage(data) {
    this.id = data.id;
    this.name = data.name;
    this.value = data.value;
}
ko.applyBindings(new ViewModel(data));

Here is my view:

<select data-bind="options: choices, optionsText: 'name', value: selectedChoice"></select>
<select data-bind="options: selectedChoice().stages, optionsText: 'name', value: selectedChoice().selectedStage"></select>

Knockout.js 2x version:

  1. Pre-selection of saved stage is working.
  2. Selected stage for choice is updated into underlying observable.

Here is the Working sample with KO 2x in js

Knockout.js 3x version:

  1. Pre-selection of saved stage is not working.
  2. Selected stage for choice is not preserved. When choice is changed, the selectedStage is set to the first item in the dropdown list each time the choice is changed.

Here is the Working sample with KO 3x

Finally, the actual question:

  1. Why does the same code behave differently with two versions of KO? Am I missing something new in KO or is it a bug in KO?
  2. What code changes should be made to produce the same functionality as in the later version of KO using the latest version of KO? My project is being developed with the latest version of Knockout.js 3.1.0, and I don't want to switch back to an older version for this functionality.
  3. Which behavior of KO version is correct, 2x or 3x? What is happening internally that causes these discrepancies in behavior?

Thanks in advance.

Answer №1

It seems like the issue is connected to 2. The way bindings are refreshed has changed
Now, you need to make sure that selectedChoice is outside of the options binding, for example:

<div data-bind="with: selectedChoice">
   <select data-bind="options: stages, optionsText: 'name', value: selectedStage"></select>
</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

Searching for similar but not identical results using Knex.js

I am seeking a solution to retrieve similar posts without including the post itself. Here is my approach: export async function getSimilars(slug: string) { const excludeThis = await getBySlug(slug) const posts = await knex('posts') .whe ...

Why is the last move of the previous player not displayed in this game of tic tac toe?

Why does the last move of the previous player not show up in this tic-tac-toe game? When it's the final turn, the square remains empty with neither an "O" nor an "X". What could be causing this issue? Here is the code snippet: The HTML code: <div ...

What is the best way to transform React API data into props that can be utilized in different components?

I've been struggling with this issue for quite some time now, unable to understand how to manipulate the data in a way that allows me to use it in other components. Although I can display the data correctly, I'm advised to structure it within a f ...

If the server goes offline, it will not produce an error message

Running a factory in AngularJS angular.module('app.services',[]) .factory('myFactory', function($http){ return { getData: function(){ return {animal: 'dog'} }, isUser: function() ...

Having trouble sending the selected value from a dropdown list to the server using $.ajax

I am embarking on my first project using JQuery (jquery-3.0.0.min.js) and JavaScript. My goal is to build a straightforward web form that connects to a database through a Web API. The form consists of various input text fields and two select dropdowns. ...

Is it possible to create a development build using Npm with React and Typescript?

I have successfully set up a TypeScript React app by using the command below: npx create-react-app my-app --template typescript However, running "npm start" generates development javascript files and launches a development server which is not id ...

Converting video titles and descriptions on YouTube | Version 3 of the API

After spending hours searching for a solution, I am still struggling to update/upload videos in multiple languages through the YouTube V3 API. I know how to set the defaultLanguage, "defaultLanguage": string I can also set the video title and description ...

The Node Express.js app is functioning properly when run locally, but displays the error "Cannot GET /" when running in a Docker container

My Node application has an Express.js server defined like this: const express = require('express') const SignRequest = require('./SignRequest/lambda/index.js') const VerifyResponse = require('./VerifyResponse/lambda/index.js') ...

Showing dynamic content retrieved from MongoDB in a list based on the user's selected option value

Implementing a feature to display MongoDB documents conditionally on a webpage is my current goal. The idea is for the user to choose an option from a select element, which will then filter the displayed documents based on that selection. For instance, if ...

Menu rollout problem when clicking or hovering

I'm facing challenges in making my menu content appear when a user clicks or hovers over the hamburger menu. My app is built using Angular, and I've written some inline JavaScript and CSS to achieve this, but the results are not as expected. Here ...

Guide to building a React project with an outdated edition of Create React App

Currently, I'm following an older tutorial to learn React, and as a result, I need to set up a project using Create React App version 1.5.2. I successfully installed <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="204352454 ...

Suggestions for a JavaScript tool that automatically crops images

Is there a tool available, either browser-based or in Java, that can analyze an uploaded image, identify different characters within it, and crop them out into separate images? For instance, if this image contains three unique runic symbols, I would like ...

having trouble installing vue on macOS using npm

Here are the steps you should follow: Instead of using node v14+, switch to node v10+. (IMPORTANT) Add the following paths to your ~/.zshrc file (if you use zsh): /Users/[yourUsername]/.npm-packages/bin /Users/[yourUsername]/.npm-global/bin After ...

What steps should be taken to validate a condition prior to launching a NextJS application?

In my NextJS project (version 13.2.4), I usually start the app by running: npm run dev But there's a new requirement where I need to check for a specific condition before starting the app. If this condition is not met, the app should exit. The condi ...

Activate single elements one at a time

If you want to understand the question better, take a look at my code on jsfiddle. Each Div contains only one link. When you click on the link, it sets the Div to active and shows a hidden Div within it. Clicking the link again toggles the active style an ...

Generate arrays with custom names by parsing JSON data

Currently, I am retrieving data from a MySQL database and converting it to JSON before passing it to a JavaScript class for chart display purposes. The challenge lies in creating arrays required by the chart from the JSON object without manually creating a ...

Adjust the color of a label based on a set threshold in Chart.js

Can anyone help me with my Chart.js issue? Here is a link to the chart: I am trying to change the color of the horizontal label when it falls between 70.00 - 73.99. Does anyone know if there's a specific option for this in Chart.js? Thanks! ...

Displaying 'Undefined' instead of 'Cleared messages count' in the Clear Command

My goal is to display the number of deleted messages on an embed, but when the embed is sent, it shows bot deleted undefined messages. Here's a screenshot: I want it to show bot deleted ex: 15 messages. It works fine as a regular message but not on a ...

Managing the scrolling direction horizontally with waypoints.js

As I work on creating a custom wizard form with waypoints, I've encountered an interesting issue that has left me puzzled. In my sample CODEPEN, you can see two pages of the wizard process to better understand the problem. Upon clicking the forward ...

Creating an AJAX XML tree without the need for a backend server language

My goal is to create a nodes tree using the information from a data.xml file, similar to what is demonstrated in this example, all done through AJAX. Can this be accomplished without utilizing a server-side programming language? I have access to the enti ...