unable to update the table due to issues with the knockout observableArray

My goal is to collect values from form fields and store them as an object in an observableArray. I want to display these objects in a table so that every time I hit the 'add' button, the table should be updated. However, I am facing issues with this functionality.

<select data-bind="options: gradeList, optionsText: 'Name', value: selectedGrade"></select>
<input type="text" data-bind="value: komark" />
<button data-bind="click: addMark">Add</button>
<table>
    <thead>
        <tr>
            <th>SN</th>
            <th>Name</th>
            <th>Mark</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: allMarks">
        <tr>
            <td data-bind="$data.id"></td>
            <td data-bind="$data.name"></td>
            <td data-bind="$data.mark"></td>
        </tr>
    </tbody>
</table>
<p data-bind="text: ;allMarks"></p>

This is my HTML code snippet. The 'gradeList' is functioning properly and displaying a dropdown menu. However, despite updating the text in the last 'p' element upon clicking the 'add' button, the table does not get refreshed.

var newModel = function () {
    var self = this;
    self.komark = ko.observable();
    self.mark = ko.observable();
    self.selectedGrade = ko.observable();
    self.gradeList = ko.observableArray([]);
    self.allMarks = ko.observableArray([]);
    self.loadAllGrades = function () {
        $.ajax({
            type: "GET",
            dataType: "text",
            url: "studenthandler.ashx",
            data: { "action": "getAllGrades", "id": 0 },
            success: function (res) {
                self.gradeList(JSON.parse(res));
            },
            error: function () {
                alert("Failed to load.\nHit Refresh.");
            }
        });
    };

    self.addMark = function () {
        // console.log("button clicked");
        self.mark({ "id": self.selectedGrade().Id, "name": self.selectedGrade().Name, "mark": self.komark() });
        console.log(self.mark());
        self.allMarks.push(self.mark());
        console.log(self.allMarks());
    };
    self.loadAllGrades();
}

The issue seems to lie within my JavaScript code. Even though the 'mark' and 'allMarks' values are getting updated in the console, the TABLE remains unchanged.

Answer №1

<td data-bind="$data.id"></td>
is not functioning as intended because no binding has been specified. To properly bind, you should use:

<td data-bind="text: $data.id"></td>
<!-- ----------^^^^^^            -->

...and the same applies for name and mark.

Here is a working example:

var newModel = function() {
  var self = this;
  self.komark = ko.observable();
  self.mark = ko.observable();
  self.selectedGrade = ko.observable();
  self.gradeList = ko.observableArray([]);
  self.allMarks = ko.observableArray([]);
  self.loadAllGrades = function() {
    /*
    $.ajax({
        type: "GET",
        dataType: "text",
        url: "studenthandler.ashx",
        data: { "action": "getAllGrades", "id": 0 },
        success: function (res) {
            self.gradeList(JSON.parse(res));
        },
        error: function () {
            alert("Failed to load.\nHit Refresh.");
        }
    });
    */
    self.gradeList.push(
      {Id: 1, Name: "Grade1"},
      {Id: 2, Name: "Grade2"},
      {Id: 3, Name: "Grade3"}
    );
  };

  self.addMark = function() {
    // console.log("button clicked");
    self.mark({
      "id": self.selectedGrade().Id,
      "name": self.selectedGrade().Name,
      "mark": self.komark()
    });
    //console.log(self.mark());
    self.allMarks.push(self.mark());
    //console.log(self.allMarks());
  };
  self.loadAllGrades();
}
ko.applyBindings(new newModel(), document.body);
<select data-bind="options: gradeList, optionsText: 'Name', value: selectedGrade"></select>
<input type="text" data-bind="value: komark" />
<button data-bind="click: addMark">Add</button>
<table>
    <thead>
        <tr>
            <th>SN</th>
            <th>Name</th>
            <th>Mark</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: allMarks">
        <tr>
            <td data-bind="text: $data.id"></td>
            <td data-bind="text: $data.name"></td>
            <td data-bind="text: $data.mark"></td>
        </tr>
    </tbody>
</table>
<p data-bind="text: allMarks"></p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>


Side note: $data.id can be simplified to just id. :-)


Side note 2: The [object Object] you're seeing for allMarks is due to applying the text binding to an array of objects. Consider using a foreach for allMarks as well.

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

What is the recommended approach for utilizing props versus global state within your components when working with JS Frameworks such as Vue?

Currently, I am delving into a larger project using Vue and I find myself contemplating the best practices when it comes to utilizing props versus global Vuex states for accessing data within a component. To elaborate, let's say I have a component re ...

Trie-based autocomplete functionality

I am currently creating an auto-completion script and I'm considering utilizing a trie data structure. My main concern is that I want all possible matches to be returned. For instance, when I type in the letter r, I expect to see all entries beginning ...

"Learn how to position a div element below the header div and above the footer div while maintaining full height in

Recently delving into the world of reactjs, I find myself facing a challenge with a page that contains 3 distinct blocks formed by divs. Have a look at the layout on my page: My Page This is the code snippet I have worked on: return ( <div> ...

How to Insert JSON into React Component's Attribute?

I am struggling with setting the value of a React component using JSON in the attribute. I want to concatenate a letter or word, but it doesn't seem to work. Is there a correct way to combine strings within a Component's attribute? In this case, ...

Vue fails to receive updates from Firestore until the page is manually refreshed

I set out to develop a task tracker app using Vue. As I neared completion of the project, I encountered an issue - when adding a new task, it would not change the reminder status unless I reloaded the page. Here is the code snippet from my Home.vue file: & ...

NextAuth: JWT callback that returns an object

I've been working on a project using Next.js (11.1.2) + NextAuth (^4.0.5) + Strapi(3.6.8). The Next Auth credentials provider is functioning correctly. However, I need to access certain user information using the session. I attempted to do this by ut ...

Is it possible to create a MongoDB query that can retrieve a specific number of documents from different types within a single collection?

If I have a collection named "pets" with three different types of animals: cat, dog, and bird What if there are 10 cats, 10 dogs, and 10 birds in the collection (30 documents total)? Can I create a query that retrieves 3 cats, 2 dogs, and 1 bird all at o ...

Dynamic website where each page is loaded based on the user's previous interaction

Can I get your opinion on something? I'm currently working on an ajax webpage. The links on my page make a GET request to the URL they are linked to, extract the div.content, and then update the content of the current div.content. Strangely, this GET ...

How can you generate a "Package Contains Lower Node Version" error message during the installation of an NPM package if the node version is higher than the current system's node version?

I am looking for a way to trigger an error during the installation of an NPM package if the node version supported by that module does not match the system/server node version. Specifically, I want to prevent the installation of any npm module that suppor ...

Error: The CommentsSection function did not return any values after rendering

I've been working on a project to create a simple web page that features multiple Material UI card components and integrates Redux to simulate a basic social media platform. The main issue I'm encountering is that when I try to expand a card, an ...

Facing issues with ng-options duplication?

I have provided the code below that I would like to display: $scope.states="India"; $scope.cities="Madhya Pradesh"; $scope.city="Ajmer"; When attempting to implement this in a cascading dropdown format, I encountered an error. You can find my jsfidd ...

Concealing Content within an Accordion

Looking for some guidance on setting up a mobile version of my product image with hover features. Currently using tooltips on desktop and planning to use a modified accordion on mobile, but struggling to make progress. Customized some JS to toggle an acco ...

What is the best method for extracting information from different websites? I typically utilize the $.post function for this task

Currently conducting a test on a javascript code located on localhost. The script is dependent on receiving data in JSON format from a remote server. Strangely, when I manually access the JSON url, the data loads without issue. However, when using JavaScri ...

What are the alternative methods to execute a React.js application without using react-scripts?

After creating my React.js app using the command below: npx create-react-app my-app I'm now looking to modify the package.json script section to run the app without react-scripts. How can I achieve this? "scripts": { "start&quo ...

Issue with window.location.href and unexpected behavior in Firefox 7

I can't seem to figure out the issue I'm encountering on FF7 My ajax calls are returning a json object (jquery). if(data.result=='ok') { var url = baseURL + "azioni/makeForm/" + data.actcode + "/DIA/" + data.az_id; console.log ...

Utilizing Angular 10 to Transform a JSON Data into a Custom String for HTML Rendering

I have received a JSON response from my backend built using Spring Boot. The "category" field in the response can either be 1 or 2, where 1 represents Notifications and 2 represents FAQs. { "pageNumber": 0, "size": 5, "totalPages&q ...

Transform a delimited string and an array of objects into a new format

Is there a way to easily convert a delimited string into an array of objects with data binding functionality? ng-list is suitable for arrays of strings. However, I have an array of objects where I want to delimit the text property for easy editing. Works ...

How can I use AngularJS to initiate code to run after the view and controller have successfully synchronized a specific change?

I am currently using AJAX to load date ranges into a pair of SELECTs (managed with AngularJS ng-repeat), which are then transformed into a slider using jQuery UI's selectToUISlider. My concern is that selectToUISlider may behave unexpectedly if the SE ...

View the edited image preview instantly upon selecting the image

I have selected an image and previewed it before submitting the form. However, now I wish to be able to edit the file immediately after selecting it, preview the changes, and then submit the file. <input type ="file" accept="image/*" id="image" name="i ...

Ways to initiate JavaScript event upon clearing input form field

I'm working on creating a dynamic search feature. As the user types in the search box, JavaScript is triggered to hide the blog posts (#home) and display search results instead (the specific script for this is not shown below). However, when the user ...