Utilizing KnockoutJS to create an observable array of objects with data retrieved from a SQL server

Currently, I am in the process of creating a proof of concept for a web application.

I am seeking guidance on how to accomplish this goal.

The data retrieved from an SQL server API consists of a class with a basic structure:

 public partial class ReqsTest
{
    public string ID { get; set; }
    public string Requisition { get; set; }
    public Nullable<System.DateTime> DateReqnRaised { get; set; }
    public Nullable<decimal> ReqnValue { get; set;}
    public Nullable<decimal> ApprovedValue { get; set; }
    public decimal Line { get; set; }
    public long INDX { get; set; }
    public string ReqStatus { get; set; }
    public string ReqBackground { get; set; }
}

To populate a Knockout Observable Array with the returned data from the server, my View Model code appears as follows:

var self = this;
self.reqs = ko.observableArray();
self.error = ko.observable();

var reqsUri = '/api/ReqsTests/';

function ajaxHelper(uri, method, data) {
    self.error(''); // Clearing error message
    return $.ajax({
        type: method,
        url: uri,
        dataType: 'json',
        contentType: 'application/json',
        data: data ? JSON.stringify(data) : null
    }).fail(function (jqXHR, textStatus, errorThrown) {
        self.error(errorThrown);
    });
}

function getAllReqs() {
    ajaxHelper(reqsUri, 'GET').done(function (data) {
        self.reqs(data);
    });
}

However, realizing that the object properties within the array are not observable, I came across the need to utilize additional functionality discussed in resources like this and here.

In attempts to resolve this, I have created a function to generate objects with Observable properties. However, there seems to be a challenge in implementing and calling this function to update the existing section of the code.

Your assistance or insights into refining the code further would be greatly appreciated.

****** UPDATED CODE ******

Index.cshtml snippet:

 <div class="page-header">
    <h1>Chamberlin Requisitions</h1>
</div>

<div class="row">

    <div class="col-xs-4">
        <div class="panel panel-default" >
            <div class="panel-heading">
                <h2 class="panel-title">Requisitions</h2>
            </div>
            <div class="panel-body panel-info ">
                <ul class="list-unstyled" data-bind="foreach: Reqs">
                    <li>
                        <div  >
                            <strong>
                                <span data-bind="text: reqs().Requisition"></span>
                                : <span data-bind="text: reqs().Line"></span>
                            </strong>
                        </div>

                    </li>
                </ul>
            </div>
        </div>
        <div class="alert alert-danger" data-bind="visible: error"><p data-bind="text: error"></p></div>
    </div> 
</div>

Updated View Model code:

function ReqsTest(rt) {
rt = rt || {};
var self = this;
self.id = ko.observable(rt.ID || 0);
self.requisition = ko.observable(rt.Requisition || "");
self.dateReqnRaised = ko.observable(rt.DateReqnRaised || null);
self.reqnValue = ko.observable(rt.ReqnValue || null);
self.approvedValue = ko.observable(rt.ApprovedValue || null);
self.line = ko.observable(rt.Line || 0.00);
self.indx = ko.observable(rt.INDX || 0);
self.reqStatus = ko.observable(rt.ReqStatus || "");
self.reqBackground = ko.observable(rt.ReqBackground || ""); }

function ReqsViewModel (){
var self = this;
self.Reqs = ko.observableArray([]);
self.error = ko.observable();

var reqsUri = '/api/ReqsTests/';

function ajaxHelper(uri, method, data) {
    self.error(''); // Clear error message
    return $.ajax({
        type: method,
        url: uri,
        dataType: 'json',
        contentType: 'application/json',
        data: data ? JSON.stringify(data) : null
    }).fail(function (jqXHR, textStatus, errorThrown) {
        self.error(errorThrown);
    });
}

function getAllReqs() {
    ajaxHelper(reqsUri, 'GET').done(function (data) {
        // Building the ReqsTest objects
        var reqs = ko.utils.arrayMap(data, function (rt) {
            return new ReqsTest(rt);
        });
        self.Reqs(reqs);
    });
}

// Fetching details
self.detail = ko.observable();

self.getReqDetail = function (item) {
    ajaxHelper(reqsUri + item.INDX, 'GET').done(function (data) {
        self.detail(data);
    });
}     
ko.applyBindings(new ReqsViewModel());

We appreciate any help you can provide. Thank you!

Answer №1

To start, create a JavaScript function that matches your ReqsTest class.

function ReqsTest(rt) {
    rt = rt || {};
    var self = this;
    self.id = ko.observable(rt.ID || 0);
    self.requisition = ko.observable(rt.Requisition  || "");
    self.dateReqnRaised = ko.observable(rt.DateReqnRaised || null);
    self.reqnValue  = ko.observable(rt.ReqnValue  || null);
    self.approvedValue = ko.observable(rt.ApprovedValue || null);
    self.line = ko.observable(rt.Line || 0.00);
    self.indx = ko.observable(rt.INDX || 0);
    self.reqStatus = ko.observable(rt.ReqStatus || "");
    self.reqBackground = ko.observable(rt.ReqBackground  || "");
}

Next, create a viewmodel to connect to the page.

function ReqsViewModel {
    var self = this;
    self.reqs = ko.observableArray([]);
    self.error = ko.observable();

    var reqsUri = '/api/ReqsTests/';

    function ajaxHelper(uri, method, data) {
        self.error(''); // Remove any existing error message
        return $.ajax({
            type: method,
            url: uri,
            dataType: 'json',
            contentType: 'application/json',
            data: data ? JSON.stringify(data) : null
        }).fail(function (jqXHR, textStatus, errorThrown) {
            self.error(errorThrown);
        });
    }

    function getAllReqs() {
        ajaxHelper(reqsUri, 'GET').done(function (data) {
            // Construct ReqsTest objects
            var reqs = ko.utils.arrayMap(data, function(rt) {
                return new ReqsTest(rt);
            });
            self.reqs(reqs);
        });
    }

    // Load the reqs - Skip if not needed
    getAllReqs();
}

Finally, link the viewmodel to the page...

ko.applyBindings(new ReqsViewModel());

You now have an array of objects with observable properties.

I manually entered this code so there may be some syntax errors.

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

Is Firebug a necessary tool for the functioning of my website?

I'm currently tackling a new project that involves complex javascript development. Unfortunately, I am unable to share any code specifics at this time. Initially, my script functioned correctly in Firefox 3.0 but encountered issues when tested on Fir ...

Encountering an HTTP parsing failure while sending XML through Angular 5's HttpClient

Struggling to access a local webservice through XML: Take a look at the code below: const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'text/xml', 'Accept': 'text/xml', 'Response- ...

Converting floating point numbers to fixed floating point numbers in JavaScript

Consider this scenario: I need to calculate 3 divided by 6, which equals 0.5 as a floating number. However, when I used the javascript toFixed(6) method to round it to 6 decimal points, it returned '0.500000' as a string instead of a floating num ...

Show or hide table columns easily without relying on jQuery

Within my HTML table that contains multiple columns, I aim to create a toggle feature for one specific column (in this case, the 4th column). Currently, I have accomplished this using jQuery: document.write('<a class="toggle" href="#!" data-alt="H ...

Tips for eliminating the domain name from the src URL attribute using Jquery

Is there a way to extract the img src attribute and retrieve only the image path without the domain name included? var imgurl = "http://nitseditor.dev/img/home/bg.jpg"; For instance, I would like to display img/home/bg.jpg instead of the full URL. Any id ...

Generating directives on the fly

I am relatively new to AngularJS and have a good understanding of the basics. My goal is to create a desktop interface where items are loaded dynamically from a database using $http. I have already developed a directive that displays a title and an icon fo ...

String that is continually changing

Hello, In my web.config file, I have defined two connection strings. <connectionStrings> <add name="AppDb" connectionString="CONNECTION-STRING1"/> <add name="LaptopDb" connectionString="CONNECTION-STRING2" /> </connectionStri ...

Is there a way to lead to a password-protected page without making it accessible through the URL?

I'm currently honing my skills in web development and embarking on a project to create an interactive puzzle website. The premise is simple - the homepage will feature just an answer input field where users can enter the correct solution to progress t ...

The WkWebView Message handler fails to return the value of the textbox initially, but successfully does so after pressing the button a second time

Having an HTML form embedded in a WKWebView in my Swift app poses a problem when trying to extract the textbox content using a message handler. The issue arises when pressing the Register button, which triggers a JavaScript function to retrieve the values ...

Obtain all subelements from the entity

In my Vue project, I am attempting to collect and POST some values to the server. However, I am finding the current implementation to be somewhat frustrating. Within a Vue method, I have a function that POSTs the collected values from the original object: ...

Arrange JSON objects within an array based on the values of three specific fields

Within an array, I am working with the following structure: [ { "playerName": "Stack", "leaguePoints": 100, "wins": 280, "miniSeries": { "progress": "WNN", "losses": 0, "wins": 1 ...

The Vue-cli webpack development server refuses to overlook certain selected files

I am attempting to exclude all *.html files so that the webpack devserver does not reload when those files change. Here is what my configuration looks like: const path = require('path'); module.exports = { pages: { index: ...

"Utilizing PHP with FTP and AJAX, or other comparable technologies

After successfully creating a PHP class for FTP server interaction (connecting, changing directories, uploading files, etc.), I am now eager to provide real-time updates to users about the actions happening on the server. For example, notifying them with m ...

Ways to attach an item using its lower point instead of its upper coordinate

I am currently working on a poker table project using React. As of now, I have player components that need to be strategically positioned around the table. https://i.sstatic.net/gX9Ij.png One challenge I'm facing is that when the screen attribute ch ...

Showing how to make an element visible in Selenium and Python for file uploading

Check out this HTML snippet: <div class="ia-ControlledFilePicker"><input class="ia-ControlledFilePicker-control icl-u-visuallyHidden" type="file" id="ia-FilePicker"><label class="ia-ControlledFilePicker-fakeControl" for="ia-FilePicker">C ...

What is the process for including an external .js file in my VueJS2 index.html?

Currently, I am faced with a challenge involving two external Javascript files that are responsible for managing animations and vector triangulation for a background animation. In a typical html/css/js project, adding these two .js files would involve incl ...

Create a mobile-friendly version of the clndr.js calendar

I am currently using a calendar created with the CLNDR plugin, which is quite impressive as it leverages underscore.js and moment.js. While the calendar functions perfectly, I am facing an issue in making it responsive for screens of varying sizes. Despite ...

The listview data source disappeared after clicking the button

On my webpage, I am using a RadListView. I populate the listview with data during the page_load event. However, I encountered an issue where the datasource of the listview gets lost when I click a button on the same page. Can anyone help me understand wh ...

Greetings Universe in angular.js

Having trouble creating a Hello World page in angular.js. When I try to display {{helloMessage}}, it shows up instead of Hello World. I'm not sure where the issue lies. Within the folder are two files: angular.min.js and HelloWorld.html. In HelloWorl ...

Pressing the button results in no action

I am currently developing a program that randomly selects 5 words from a database and inserts them into an array. Although the page loads correctly initially, nothing happens when the button is clicked. None of the alerts are triggered, suggesting that the ...