Leveraging d3.js for sending multiple JSON requests and mapping data to various elements

I've been working on setting up a configuration page where users can reconcile unmatched data by choosing from a list of possible matches. The backend generates the list of items that need to be matched, and then a JS function is used to fetch the list of potential matches and populate the corresponding select element. Currently, I'm utilizing D3.js for the selection and updating process.

At this point, it seems like everything is being connected correctly through the .data() function, but only the last select option is getting populated with its choices.

Below is the JavaScript code responsible for fetching the JSON data and filling in the select elements. This code runs after the window has loaded:

function attach_options() {
    opts = d3.selectAll("select[data-opt-table]")
    opts.each(function(p,j) {
        obj = d3.select(this)
        opt_table = obj.attr('data-opt-table')
        opt_field = obj.attr('data-opt-field')
        opt_disp = obj.attr('data-opt-disp')
        opt_lookup = obj.attr('data-opt-lookup') 
        d3.json("{% url 'get-opts' %}" + opt_table + '/' + opt_field + '/' + opt_disp + '/' + opt_lookup + '/').then(
            function(data) {
                options = obj.selectAll('option').data(data.opt_list)
                options.join('option')
                    .attr('value', d => d.pk)
                    .text(d => d.disp_value)
            }
        )
    })
}

Here is an example of what a JSON response looks like:

{
  "opt_list": [
    {
      "pk": "DE-001",
      "disp_value": "Kent"
    },
    {
      "pk": "DE-003",
      "disp_value": "New Castle"
    },
    {
      "pk": "DE-005",
      "disp_value": "Sussex"
    }
  ]
}

Answer №1

When you pass the function to d3.json, it executes asynchronously. This results in the variable obj being overwritten by a subsequent loop execution. To remedy this issue, consider encapsulating d3.json within an additional function that takes obj as a parameter. Here is an example using an anonymous function:

function attach_options() {
    opts = d3.selectAll("select[data-opt-table]");
    opts.each(function(p,j) {
        obj = d3.select(this);
        opt_table = obj.attr('data-opt-table');
        opt_field = obj.attr('data-opt-field');
        opt_disp = obj.attr('data-opt-disp');
        opt_lookup = obj.attr('data-opt-lookup'); 
        ((obj) => {
            d3.json("{% url 'get-opts' %}" + opt_table + '/' + opt_field + '/' + opt_disp + '/' + opt_lookup + '/').then(
                function(data) {
                    options = obj.selectAll('option').data(data.opt_list)
                    options.join('option')
                        .attr('value', d => d.pk)
                        .text(d => d.disp_value);
                }
            );
        })(obj);
    });    
}

View a functional example here.

Additionally, always remember to use semicolons when writing JavaScript.

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

Can you point me towards the location of Sigma.js' sigma.utils.xhr() function?

I came across a peculiar issue with lines 23 and 24 of sigma/plugins/sigma.neo4j.cypher/sigma.neo4j.cypher.js: sigma.neo4j.send = function(neo4j, endpoint, method, data, callback) { var xhr = sigma.utils.xhr(), Surprisingly, sigma/src/utils/sigma.uti ...

How can I sync changes between two variables in node.js?

Is there a method to create a shared variable in JavaScript? Here is an example of what I am attempting to achieve: var id = 5; var player = new Player(id); var array1[0] = player; var array2[0] = player; array1[0].id = 8 console.log(array1[0]); // ...

using database URL as an AJAX parameter

I am currently working on a Python CherryPy controller that needs to validate a database URL by attempting a connection. However, I am facing challenges with passing the parameter to the method. Below is my AJAX call: $.ajax({ async: false, ty ...

Update a specific line in a file with node.js

What is the most efficient way to replace a line in a large (2MB+) text file using node.js? Currently, I am accomplishing this by Reading the entire file into a buffer. Splitting the buffer into an array by the new line character (\n). Replacing th ...

Implementing Title Attribute in Grid View Template Field

I have implemented a Grid View with a "TemplateField" that includes properties for Header Text and SortExpression set to true. Upon inspecting the browser, I noticed that it generates an anchor element with some JavaScript. How can I add a title tag to t ...

Dealing with Javascript Array/Serialization in C# (.NET)

I have implemented tableDnD to rearrange table rows and then serialized them using the function "$.tableDnD.serialize()". Now, I need to pass this serialized data to C# for further processing. What is the most effective way to do this? Below is a sample ...

Each piece of data is unique and when accessed, its value is undefined

I'm facing an issue with a product div that has the data-product attribute with an object value. My goal is to transfer this product data into gtag. However, I'm only getting one piece of data each time I try and when I attempt to access data.id ...

Using regular expressions to enable scientific notation in a numeric text field

I'm looking to create a validation system for numbers with scientific notation (using 'e', '+', '-', '.') using regex. I've tried some expressions but they are not working as expected. For Regular Numbers: ...

What is the best way to showcase only the most recent data that has been received

Hey there, I'm working on a way to display only the most recent message of the day, However, I'm facing an issue where my code is always selecting the first message instead of the latest one. Even though it's not the initial object in the ...

Move the DIV element to a static section within the DOM

In my Vue app, I have implemented methods to dynamically move a DIV called 'toolbox' to different sections of the DOM. Currently, the DIV is positioned on the bottom right of the screen and remains static even when scrolling. My goal is to use t ...

Using global variables in NodeJS MySQL is not supported

Why am I unable to access the upcoming_matches array inside the MySQL query callback? Whenever I try to log upcoming_matches[1], I get a 'TypeError: Cannot read property '1' of null' error message in the console. This indicates that th ...

The JSON parser encountered an unexpected token 'S' at the very beginning of the string in the Next auth

My colleague and I are collaborating on the development of an application portal. Despite having identical code, node versions, and environment variables, he is encountering an error when trying to log in while I am able to do so without any issues. Strang ...

JavaScript recursive reduce function

Looking to filter through an Array of objects and extract only those with the key is_enabled=true from another Array of objects. Structure of the data: [ { 'id': 1, 'label': 'Label1', 'option ...

Encountering issues with parsing normals in THREE.js json mesh format

UPDATE: The demo is finally live! Check it out here: . Use the dropdown menu to switch between torus models and see the issue in action. Please note that WebGL MRT extensions are required for this demo. I have been working on developing my own WebGL defer ...

Is it best practice to contain all side effect logic within useEffect in React?

I am looking to monitor user clicks on a button and send the data to the server. I am considering where to implement the logic for "sending the data to server" within my component. Should I include it inside the onClick handler or should I move it to use ...

How to utilize the respond method in Grails version 2.3.6 for returning JSON data along with a specific status

Trying to utilize the respond method in grails 2.3 for returning exception messages and status codes in JSON format has been a bit challenging so far. An ExceptionController has been set up to manage exceptions thrown by other controllers: class Exceptio ...

Learn how to obtain a response for a specific query using the `useQueries` function

Can we identify the response obtained from using useQueries? For instance, const ids = ['dg1', 'pt3', 'bn5']; const data = useQueries( ids.map(id => ( { queryKey: ['friends', id], queryFn: () =&g ...

Updating a numeric field in Mongoose by a percentage of its current value

Looking for a way to reduce prices of items in Mongoose. { name:"itemname", price: 30 } I want to apply a 10% reduction to the price, but $inc and $mul won't work for this scenario. {$mul: {price:0.10}} This code would reduce the price to 10% of t ...

Removing specific text from a textarea containing a vast quantity of information

I developed a simple XML formatter using HTML and Javascript. I am looking to incorporate a delete feature into it. Essentially, I want the ability to remove an entry without affecting any other data. <contact <!--Jane Smith--> first_name="Jane" ...

Utilize the new JSON capabilities in MySQL 5.7 to retrieve rows as JSON output

Exploring the latest JSON capabilities, I wanted to find a smart (or simple) way to retrieve a rowset as a JSON object without explicitly naming keys or resorting to string manipulation. For instance: TABLE: people id name age 1 bob 54 ...