Retrieving data from an AJAX call and populating a knockout.js observableArray()

This phenomenon confuses me. There must be some small detail that I am missing here. My goal is to load a simple observableArray in knockout using an ajax call.

javascript

// We initialize the array with an empty array.
var data = [];   
var viewModel = {
    vendors: ko.observableArray(data)
};
ko.applyBindings(viewModel);

$(function () {
    // When this click event occurs, we populate the observable array
    $('#load').click(function () {
        // WORKS. Html is updated appropriately.
        viewModel.vendors([{ "Id": "01" },{ "Id": "02" },{ "Id": "03" }]);

        // DOES NOT WORK. Fiddler2 shows the exact same JSON string coming back 
        // as in the example above, and the success function is being called.
        $.ajax({
            url: '/vendors/10',
            dataType: 'json',
            success: function (data) {
                viewModel.vendors(data);
            }
        });
    });
});

html

<button id="load">Load</button>
<ul data-bind="template: { foreach: vendors }">
    <li><span data-bind="text: Id"></span></li>
</ul>

Question: Why does the successful ajax call, where the value of the data variable perfectly matches the hard-coded value, fail to trigger the HTML refresh?

Answer №1

There seems to be no obstacle preventing this from working properly, as evidenced.

http://jsfiddle.net/madcapnmckay/EYueU/

I suggest verifying that the ajax post is indeed returning json data, ensuring that the json is in array format, and confirming that it is being parsed correctly.

I made some adjustments to the ajax call in order for the fiddle ajax handlers to function correctly.

I cannot think of anything else at the moment.

I hope this explanation proves helpful.

Answer №2

let instance = this;
//instance declared first in the model

$.ajax({
            url: ",
            dataType: "json",
            contentType: 'application/json',
            type: "POST",
            data: JSON.stringify({ }),
            processdata: true,

            beforeSend: function () {
                $.mobile.loading('show');
            },

            error: function (xhr, textStatus, errorThrown) {
                alert('Sorry!');
            },

            success: function (data) {

                $.mobile.loading('hide');
                if (data.result!= '') {
                    instance.vendors(data.result);

                } else {
                    instance.vendors({something});

                }
            }
        });

Instead of using viewModel.vendors, use self.vendors

Answer №3

Here is the approach I took in developing my MVC .net application using knockout and jquery.

// My Scripts/groItems.js
(function () {

    var ViewModel = function () {
        items = ko.observableArray(),
            ItemName = ko.observable(),
            Img = ko.observable(),
            Qty = ko.observable()
    }

    $.getJSON('/Items2/AllItems', function (data) {
        for (var i = 0; i < data.length; i++) {
            self.items.push(data[i]);
        }
    });

    var vm = new ViewModel();

    $(function () {
        ko.applyBindings(vm);
    });

}());
@model IEnumerable<GroModel.Item>
@{
    ViewBag.Title = "Index";
}

<p>
    @Html.ActionLink("Create New", "Create")
</p>

<div data-bind="text: items().length"></div>
<table class="container table table-hover">
    <thead>
        <tr>
            <th>Item name</th>
            <th>img</th>
            <th>qty</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: items">
        <tr>
            <td data-bind="text: ItemName"></td>
            <td data-bind="text: Img"></td>
            <td data-bind="text: Qty"></td>
        </tr>
    </tbody>
</table>

@section Scripts {
    <script src="~/Scripts/knockout-3.4.2.js"></script>
    <script src="~/Scripts/groItems.js"></script>
}

Here's a snippet from Items2Controller.cs where I fetch all items:

    private GroContext db = new GroContext();
    public JsonResult AllItems()
    {
        return Json(db.Items.ToList(), JsonRequestBehavior.AllowGet);
    }

https://i.sstatic.net/9zacC.jpg

I hope this explanation proves to be useful. Thank you!

Answer №4

A clever workaround involves utilizing a basic JavaScript utility function.

By replacing viewModel.vendors(data); with eval (make sure to investigate the risks associated with using eval), you can achieve the desired outcome.

eval("viewModel.vendors("+JSON.stringify(data)+");");

Answer №5

I believe there may be a bug in the system. It seems that Knockout's sample works fine when wrapped in a class:

public class ResultWrapper
{
    public Title {get;set;}
    public List<Result> {get;set;}
}

However, if we try to return Results directly, it seems impossible to bind it without using applyBindings!

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

Visualization of data using Highcharts rose diagram utilizing JSON format

I have a PHP script called data.php that retrieves JSON data from a MySQL database. Here is an example of the data: [[0,0.35,0,1.05,1.05,0.7,0.35], [0,0.7,0,1.05,1.74,1.74,0], [0,2.09,0,0.7,2.09,1.05,0.35], [0.35,1.74,0,1.05,1.05,1.05,0.35], [0.7,0.7, ...

Ways to display only particular dates in react-dates

I am working with an array of dates. const availableDates = ["2019-02-01", "2019-02-04", "2019-02-05", "2019-02-06", "2019-02-07", "2019-02-11", "2019-02-12", "2019-02-13", "2019-02-14", "2019-02-15", "2019-02-19", "2019-02-20", "2019-02-21", "2019-02-22" ...

What steps can be taken to ensure that a WebSQL query does not return negative

Here's the code snippet I am currently using: function decrementCart(quantity, id){ db.transaction(function(tx){ tx.executeSql("UPDATE cart SET quantity=(quantity -1) WHERE id=?", [id]) ...

Angular Automatically Generated Identifier for Event Detection

By using jQuery, I can easily target an ID that starts with "conditionValue" $(document).on('focus', "[id^=conditionValue]", function (event) { // code }); But how can I achieve the same in Angular when looking for an ID starting with somet ...

Passing a JSON object to a ViewModel in a .Net Core REST API

I am facing an issue with my ViewModel that is initialized as dto. When I try to send a json object from postman with their values, the c# object does not seem to take the values and remains null. How can I resolve this? public class RegisterUserVm { ...

Clicking multiple times will impede the progress of AJAX requests

My webpage has multiple buttons that can be clicked very quickly, but it seems like Chrome is struggling to keep up with the speed? $(document).ready(function() { $('.favorite-button').unbind('click').click(function() { addLine ...

Having trouble getting the CSS class to work in MVC4 with jQuery implementation

I recently created a view page where I implemented some jQuery code: <script type="text/javascript"> $(document).ready(function () { var hdrname = $('#headername').text(); alert(hdrname); if (hdrname == "Pending Assignment") { ...

Can Jquery be used to swap out specific li content?

<div class="widget_ex_attachments"> <ul> <li> <i class="fa fa-file-word-o"></i> <a href="uploads/2014/09/Parellel-universe.docx">Parellel universe</a> </li> ...

Establish the predefined date for the air-datepicker

I am currently utilizing the air-datepicker inline feature. My objective is to establish the starting date for it. Below is the script detailing my attempt: export function load_datepickers_inline():void { const search_legs_0_datepicker = $("#search_leg ...

What is the best way to store and retrieve all the variable data from a .js file on a user's device?

I'm looking for a way to save and load multiple variables in JavaScript that determine a "save" state. These variables are stored in a file named "variables.js." Is there a simple method to easily save all the information in this file and then load i ...

Simple Way to Modify Color of Active Page Link - HTML, CSS, and JavaScript

I found a helpful example on how to change link colors for the current page here. Here is the script I added: <script> // current page highlight $(document).ready(function() { $("[href]").each(function() { if (this.href == window.l ...

What is the best way to implement a keypress event in this code?

As a JavaScript and jQuery newbie, I have a question regarding adding a simple key press action to this code. How can I implement functionality where pressing the Right Arrow key takes me to the next image, and pressing the Left Arrow key takes me to the p ...

Modify the ColVis Appearance in Datatable Using JavaScript

Where can I modify the background color for the 'Hide/Show columns' label in the ColVis.js file? ...

Tips for utilizing json_decode to extract specific data within a JSON structure

Hi, I have recently started learning php and I am looking for some quick assistance with json_decode/php. Specifically, I need help retrieving the values of g91 in an array. Is there a recursion value that can be passed to json_decode for this? { "e": ...

Extract information from a URL without the need for a page reload or user interaction

Recently, I developed a form that accepts YouTube links and extracts the ID using parsing/regex. The function is triggered by clicking a button, which then displays the ID of the URL. Is there a way to show the ID without requiring a button click or page ...

Positioning of Cloned Element in jQuery

When a user presses enter while in one of the text input fields provided, I want to add a new empty text input field directly below it - and before the other existing ones. The code snippet below currently adds the new field at the end of the container, bu ...

Creating a function in Angular to locate each object based on its ID

Hello there, I am currently working on creating a method called findChildByIdInData(data:any, childId:string). This method will take in a JSON main node with children that have unique IDs, and the goal is to find a specific object based on the ID provided ...

Determine the quantity of items within a JSON array

There is a json array located at the following url: http://localhost/heart/api/restApiController/dataset.json The structure of the json array is as follows: [ { Weight: "3", Smoking: "1", Exercising: "0", Food_habits: ...

Fixing a JavaScript conflict between the parent theme and the child theme in WordPress

Recently, I created a customized child theme based on the Divi Theme, tailor-made for integration with Buddypress. Everything was going smoothly until I encountered a conflict involving the commenting buttons due to a script. In my theme, there is a JavaS ...

Is there a way to automatically close a created div by clicking anywhere outside of it?

I'm facing an issue with a dynamically created div that I want to close by clicking outside of it. However, when I try to achieve this functionality, the div closes immediately as soon as it is opened. closediv(); } function closediv() { d ...