Observable Knockout Dependency

I found an interesting example on the KnockoutJS site () and I want to implement something similar.

My goal is to check if certain values are available on the client side when a category is selected. If they are not, then I need to fetch them from the server. Unlike the example provided, where the products are already on the client side, in my case I need to first check on the client and only go to the server if the data does not exist.

Can anyone provide me with an example or offer any tips on how to achieve this?

Thank you in advance!

Here is the code snippet I have tried (JavaScript):

function getJsonObject(value) {
            return $.parseJSON(value.replace(/"/ig, '"'));
        }

        var sg = getJsonObject('@ViewBag.SchoolGroups');
        var temp = {
            schoolGroups: sg,
            schoolsBySchoolGroup: undefined,
            getSchools: function (schoolGroupId) {
                alert(schoolGroupId);
                if (this.schoolsBySchoolGroup === undefined) {

                    //get data from server
                }
                else {

                    //verify if data exists

                    //if not, retrieve from server
                }

                return "something...";
            }
        };    

$(document).ready(function () {

                var CartLine = function () {
                    var self = this;
                    self.schoolGroup = ko.observable(sg[0].Id);
                    self.school = ko.observable();

                    // Whenever the category changes, reset the product selection
                    self.schoolGroup.subscribe(function () {
                        self.school(undefined);
                    });
                };

                var Cart = function () {
                    // Stores an array of lines, and from these, can work out the grandTotal
                    var self = this;
                    self.lines = ko.observableArray([new CartLine()]); // Put one line in by default

                    // Operations
                    self.addLine = function () { self.lines.push(new CartLine()); };
                    self.removeLine = function (line) { self.lines.remove(line) };
                };

                ko.applyBindings(new Cart());
            });

HTML code:

 <table>
                        <thead>
                            <tr>
                                <th>Start Date</th>
                                <th>School Group</th>
                                <th>School</th>
                                <th></th>
                            </tr>
                        </thead>
                        <tbody data-bind='foreach: lines'>
                            <tr>
                                <td>
                                    <input class='required datepicker' />
                                </td>
                                <td>
                                    <select data-bind='options: temp.schoolGroups, optionsText: "Name", optionsValue: "Id", value: schoolGroup'></select>
                                </td>
                                <td data-bind="with: schoolGroup">
                                    <select data-bind='options: temp.getSchools($parent.schoolGroup.Id), optionsText: "Name", optionsValue: "Id", optionsCaption: "Select...", value: $parent.school'></select>
                                </td>
                                <td>
                                    <a href='#' class="none" data-bind='click: $parent.removeLine'><i class="icon-remove"></i></a>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <a href='#' class="none" data-bind='click: $root.addLine'><i class="icon-plus"></i></a>

I attempted using $parent and $data without success...

Answer №1

Using a JSFiddle, I have created a simulation where server calls are mimicked by time delays. When a category is selected, the subcategories are retrieved from the server and stored within the category item. As a result, if the same category is reselected, the subcategories are not fetched from the server again.

var Category = function (title) {
    var self = this;
    self.subcategories = ko.observableArray(null);
    self.title = title;
};

var ViewModel = function (categories) {
    var self = this;
    self.selectedCategory = ko.observable();
    self.availableCategories = categories;

    self.selectedCategory.subscribe(function (item) {
        if (item.subcategories()) {
            self.availableSubcategories(item.subs());
        } else {
            serverCall(item.title, function (subCats) {
                item.subcategories(subCats);
                self.availableSubcategories(subCats);
            });
        }
    });

    self.selectedSubcategory = ko.observable();
    self.availableSubcategories = ko.observableArray();
}

var viewModel = new ViewModel([new Category('Cat1'), new Category('Cat2'), new Category('Cat3')]);

ko.applyBindings(viewModel);

var serverCall = function (category, callback) {

    setTimeout(function () {
        var array = [];
        for (var index = 0; index < 5 ; index++) {
            array[index] = category + ' - ' + index;
        }
        alert('Server Call');
        callback(array);
    }, 1000)

};

I trust that this explanation is clear and beneficial to you.

Answer №2

Performing the following actions within the subscribe handler is recommended. Below is a basic example in pseudo code:

self.category.subscribe(function () {
  if (values exist on client)
    self.product(values from client);

  else
    // initiate ajax call to retrieve values
});

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

Why use getElementById(id) to obtain an element in JavaScript when it already exists in the JS?

Recently, I have observed that a reference to an HTML element with an id can be easily accessed in JavaScript by using a variable named after that id (jsbin). What is the reason for this behavior? Why do we need to use getElementById(id) when we could sim ...

Issue with Submit Button Functionality following an Ajax Request

I am facing an issue where the submit button does not work after an ajax call, but works fine if I reload the page. The problem arises when a modal is displayed for email change confirmation. If the user confirms the change, the form submits successfully. ...

inserting a dynamic variable into a JSON string

My goal is to create a javascript object, var systemName = {"system" : varA}; However, I want the object to be structured like `{"system" :"varA"} where varA contains the variable value but is enclosed in double quotes. I attempted {"system" : "'+ ...

Using jQuery to create clickable images by enclosing them in an `<a>` tag

How can I make each image with a specific class clickable? I would like jQuery to: Retrieve the src attribute of the image. Enclose the image within an a href tag that includes that src URL. .clickable { padding: 20px; border: 1px ...

NextJs application displaying empty homepage and preventing redirection

After successfully deploying my nextjs app on netlify, I encountered a strange issue. When I visit the base url of my website, instead of seeing the homepage, all I get is a blank screen. Oddly enough, if I navigate to specific pages on my site, they load ...

Unable to locate additional elements following javascript append utilizing Chrome WebDriver

I have a simple HTML code generated from a C# dotnet core ASP application. I am working on a webdriver test to count the number of input boxes inside the colorList div. Initially, the count is two which is correct, but when I click the button labeled "+", ...

Prevent onlick actions until JavaScript function has completed

I run a dynamic quiz website using PHP, JavaScript, and MySQL. The quiz consists of multiple choice questions with answer options displayed on four buttons. <input type = "button" value="$alt1" onClick="changeQuestion('alternative1'); this.st ...

Tips on displaying a particular JSON attribute?

After starting with a JSON string, attempting to convert it into a JSON object and then trying to print a specific field (such as firstName), I am getting undefined. What could be the issue here? Thank you for your help! var string = '{"firstName ...

Is there a way to customize the CSS for a single blog post and add a 5-star rating system without affecting other posts?

After launching my blog on Google's Blogger, I wanted to add a unique touch by incorporating a static 5-star rating system in my Books I Read Section. I thought about using CSS to customize each book post and display anywhere from 1 to 5 stars for vis ...

Stopping form submission on a jQuery form

I am in the process of implementing a password control feature on a login form using jQuery and ajax. This is the current script I have: $(document).ready(function() { $("#login-form").submit(function(e) { var csrftoken = getCookie('csr ...

Learn the steps to successfully select a drop-down option by clicking on a button

Below is the HTML code for my select options: <select id="font"> <option value="School">School</option> <option value="'Ubuntu Mono'">SansitaOne</option> <option value="Tangerine">Tange ...

Massive HTML Table Containing Rows upon Rows

Currently, I have a server that can provide me with a list of objects in json format, and my goal is to showcase them in a table on the client side. Initially, I thought about dynamically modifying the DOM after receiving data from the server. Building th ...

When using React, it's important to verify if the page has been refreshed before updating the local storage based on the GraphQL query. If the page

Currently, I am working on implementing a hit counter feature that increments each time a user clicks a button. The setup involves GatsbyJS with React and utilizes a lambda function to store the count in FaunaDB. Additionally, the client-side functionality ...

What is the best way to choose a random number using jQuery?

<div class="yyy"></div> <p>...</p> <pre><code>let content = $(".xxx").text(); $(".yyy").html(content); http://jsfiddle.net/tQeCv/ I just require this specific input : Number is {1|2|3|4}, and {one|two|three|four} ...

Changing the value in a URL String using JavaScript

I am in possession of a String that contains a URL resembling the following: var url ="http://ispeakphone.com/checkout/cart/add/uenc/aHR0cDovL2lzcGVha3Bob25lLmNvbS9zYW1zdW5nL3NhbXN1bmctZ2FsYXh5LXMvZ2FsYXh5LXM5LXBsdXMuaHRtbA,,/product/619/form_key/foxmD7jg ...

Using jQuery to establish a canvas element and define its dimensions by adjusting its width and height attributes

My attempt at using jQuery to create a canvas element was not quite as expected. Here is the code I tried: var newCanvas = $('<canvas/>',{'width':100,'height':200,'class':'radHuh'}); $(body).append(n ...

Using a Javascript library within an Angular component: A comprehensive guide

I've been working on a Web-Client project that involves visualizing sensor data such as velocity and acceleration within a coordinate system. In order to display this coordinate system, I decided to use the graph.js library from https://github.com/dhu ...

Tips for transforming a React sign in component into an already existing Material UI sign in component

I am looking to revamp my current sign-in page by transitioning it into a material UI style login page. Displayed below is the code for my existing sign-in component named "Navbar.js". This file handles state management and includes an axios call to an SQ ...

Server has sent an Ajax response which needs to be inserted into a div

I have a modal window that sends a POST request to the server. Before returning to the view, I store some information in ViewData. Here's an example of what I'm doing: ViewData["Msg"] = "<div id=\"msgResponse\" class=\"success ...

Tips for executing an SQL query containing a period in its name using JavaScript and Node.JS for an Alexa application

Hello there, I've been attempting to make Alexa announce the outcomes of an SQOL query, but I'm encountering a persistent error whenever I try to incorporate owner.name in the output. this.t("CASEINFO",resp.records[0]._fields.casenumber, resp.r ...