ajax call triggering knockout foreach update

Within my ViewModel, I have defined a variable called self = this; Another foreach binding is working in my code, but it is not within an ajax request. The initial UI load is functioning correctly. I have confirmed that self.wikiData is being updated by testing with console.log(self.wikiData());, but the update is not reflecting in the UI. I have a similar setup working outside the ajax request.

self.wikiData = ko.observableArray([{title: ko.observable("testing"), url: ko.observable("code")}, {title: ko.observable("this"), url: ko.observable("works")}]);
  
$.ajax({
  url: "http://en.wikipedia.org/w/api.php?action=opensearch&search=" + marker.title + "&callback=wikiCallBack",
  dataType: 'jsonp',
  success: function(response) {
    // issue with updating ko array
    // Clear wikiData array's contents
    self.wikiData = ko.observableArray([]);
    var articleList = response[1];
    if (articleList.length < 1) {
      self.wikiData.push({ title: ko.observable("No articles found), url: ko.observable("#") });
    }
    for (var i = 0; i < articleList.length; i++) {
      articleStr = articleList[i];
      self.wikiData.push({ title: ko.observable(articleStr), url: ko.observable("http://en.wikipedia.org/wiki/" + articleStr) });
    }
    // Push wiki attribution regardless of whether articles were found
    self.wikiData.push({ title: ko.observable("Courtesy of Wikipedia API"), url: ko.observable("https://www.mediawiki.org/wiki/API:Main_page") });
    if (self.isWikiMenuVisible() === false) {
      self.clickHamburgerWiki();
    }
  }
});
<ul data-bind="foreach: wikiData">
  <li class="wiki-list-item">
    <a data-bind="text: title, attr:{href: url}"></a>
  </li>
</ul>

Answer №1

Discovered the solution. I decided to remove the observables as I realized I only needed to track the objects in the observableArray, without manipulating the data within the objects themselves. Here is the revised code:

$.ajax({
  url: "http://en.wikipedia.org/w/api.php?action=opensearch&search=" + marker.title + "&callback=wikiCallBack",
  dataType: 'jsonp',
  success: function(response) {
    // TODO figure out why ko array isnt updating
    // articleList is just an array is strings
    var articleList = response[1];
    var tempArray = [];
    if (articleList.length < 1) {
      tempArray.push({
        title: "No articles found",
        url: "#"
      });
    } else {
      for (var i = 0; i < articleList.length; i++) {
        articleStr = articleList[i];
        tempArray.push({
          title: articleStr,
          url: "http://en.wikipedia.org/wiki/" + articleStr
        });
      }
    }
    tempArray.push({
      title: "Courtesy of Wikipedia API",
      url: "https://www.mediawiki.org/wiki/API:Main_page"
    });
    // Clear wikiData array's contents by redefining with new content
    self.wikiData.removeAll();
    tempArray.forEach(function(item) {
      self.wikiData.push(item);
    });
    // Push wiki attribution regardless of whether articles were found
    //clearTimeout(wikiRequestTimeout);
    if (self.isWikiMenuVisible() === false) {
      self.clickHamburgerWiki();
    }
  }
});

No changes in the HTML.

As it turns out, the way to ensure KO recognizes updates was to utilize the removeAll() function to clear the observableArray and then add new objects to it, rather than resetting the observableArray to an empty array. This approach makes sense since reassignment removes previous bindings, whereas removeAll() preserves them.

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

A step-by-step guide to effectively stubbing a dependency within an express middleware using a combination of express-validator, mocha, chai, sinon,

**Edit: Re-created with a simple example that works first: I have an example file and two modules. moduleA has a dependency called moduleB // moduleA.js const ModuleB = require('./moduleB'); function functionA() { return 20 + ModuleB.functio ...

Tips for using conditional rendering with React and TypeScript

Issue with Conditional Rendering in TypeScript It seems like I might have encountered a problem with the way I declare my components. Take a look at this TypeScript snippet: import React, { FunctionComponent } from 'react'; export const Chapte ...

Express.js problem: Unable to load CSS and JS files from the 'public' directory

Currently, I am working on a web project with Express.js and encountering difficulties in loading CSS and JavaScript files from the 'public' folder. Despite following common practices, it seems that something is amiss. Here is the layout of my pr ...

Incorporate highcharts data into your Laravel project using the power of AJAX

Encountering an issue with loading data for a Highcharts chart. The response from my controller provides the following data: [['Doctorado', 91.86],['Maestría', 6.98],['Licenciatura', 1.16]] Although the AJAX call is succes ...

I'm struggling to solve a straightforward jQuery sliding issue

I am struggling to make text slide from right to left on my website. I want the text to appear only when the page loads or refreshes, and then slide off when a link is clicked, revealing new text. Can anyone help me figure this out? http://jsfiddle.net/XA ...

How to Retrieve Upload Progress via HTTP Request in PHP

Is there a way to monitor the progress of file uploads by accessing the HTTP request in PHP? If so, how can this be achieved when uploading files into a MySQL database? require('../connect_db.php'); //Collect all necessary data $name = $dbc-> ...

Add a Page to Your Domain Name using the Text Input Box

I'm looking to create an input field that allows users to enter a text string, which will be added to a domain name when submitted, redirecting the user to a specific page. Here's how the process works: The user enters 'foo' into the ...

Transform a loaded image into canvas

I have encountered a challenge while working on a plugin where I need to convert an Image into Canvas and store it as data URL. The function currently triggers on the 'load' event, but how can I achieve this conversion for an image that is alread ...

JavaScript plugin designed for effortless conversion of JSON data to structured HTML code

I want to add this JSON data to an HTML element. [ { "website":"google", "link":"http://google.com" }, { "website":"facebook", "link":"http://fb.com" } ] Is there an easy way to convert this using a plugin ...

What is the best way to retrieve the value of an input field in React when incorporating Material UI components?

I am working with a few radio input components that have been imported from material Ui react. Each radio input is wrapped in a FormControlLabel component. <FormControlLabel onClick={checkAnswerHandler} value={answer} control={<Radio color=&quo ...

Exploring the dynamic duo of Django and DataTables: a guide on incorporating

Have you cautiously attempted to fetch data using AJAX, and displaying it in a datatable works seamlessly, but the issue arises when attempting to search or sort within the table. It seems that upon doing so, the data is lost, necessitating a page reload. ...

Running the nextjs dev server with configuration settings inherited from a different project

Currently, I am working on a Next.js application. I have a folder named landing/pages/ inside the root folder, and I want to run the development server with those pages by using next dev ./landing. The idea is to create a separate app using the same codeba ...

Is there a potential security flaw in jQuery when using $.get(code_url) to execute the returned code without relying on eval() or appending it to the DOM

As I was debugging my NodeJS application, I stumbled upon a surprising discovery: when using jQuery with a simple $.get(code_url) where code_url is a URL leading to server-side JavaScript code, the code gets executed. The expected behavior should be: $.g ...

Discover a class located following a specific element even when they are not directly related

There is a group of elements all with the class month. Some of them also have the class cal, while only one has the class today. The goal is to locate the first element with the class cal, but only after finding the element with the class today. The chall ...

How can I utilize the mapv tool created by Baidu in a Node project?

I need assistance converting the following code to a node environment. The code can be found at Here is the code snippet: var map = new BMap.Map(slice.selector, { enableMapClick: false }); // Create Map instance map.centerAndZoom( ...

Having difficulties in Vue while attempting to access a particular row

I encountered an error message stating Uncaught TypeError: snapShotChnaged.forEach is not a function. My goal is to retrieve specific row data, which is why I am utilizing the doc method. retrieveSpecificDonation() { firestore .collection('d ...

How to Transform JSON Element into a JavaScript Array in AngularJS?

Implementing AngularJS to fetch values in JSON format using $resource call. The model element I require is a Javascript array structured as: [ [1328983200000, 40], [1328983200000, 33], [1328983200000, 25], [1328983200000, 54], [1328983200000, 26], [1328 ...

Creating new rows dynamically with jQuery

In my current setup, there is a table with one row and two columns - a textbox and a button: $(function() { var i = 1; $('#add').click(function() { i++; $('#dyn').append('<tr id="row' + i + '">&l ...

How can one address the issue of undefined data within table cells?

I have encountered an issue while reading and displaying an XML file on a webpage using a JavaScript script. The problem arises when the page loads, and the information inside the cells of the table shows as "UNDEFINED". The intended display should include ...

When buttons contain an image instead of text, event.target.value will be undefined

I'm facing an issue with two buttons that are almost identical, except one includes an image while the other has text content. I have added onClick event handlers to both of them. Oddly, the event.target.value for the image button is coming up as und ...