Executing a Javascript callback function within a forEach loop

Javascript:

$(document).ready(function() {
    var systemsInfo = 'https://raw.githubusercontent.com/joeberthelot88/EVE-Online-Mapper/master/eveSystems.json?token=AWUj7mQ8T_6NBaRgIcz4Xz0KQd1SazMUks5ZjpeAwA%3D%3D';

    var constellationsList = [20000441, 20000442, 20000443, 20000444, 20000445, 20000446, 20000447];

    var arrayXCoords = [];
    var arrayYCoords = [];

    $.getJSON(systemsInfo, function(data) {

        data.forEach(function(sysData) {

            // Extract information and create elements for objects found in constellations list
            if(constellationsList.indexOf(sysData.constellation_id) > -1) {

                // Simplify location coordinates
                var xCoord = sysData.position.x / 100000000000000;
                var yCoord = sysData.position.y / 100000000000000;

                // Store coordinates in arrays
                arrayXCoords.push(xCoord);
                arrayYCoords.push(yCoord);

                // Get the lowest coordinate values
                var offsetXValue = Math.min.apply(Math, arrayXCoords);
                var offsetYValue = Math.min.apply(Math, arrayYCoords);

                // Set pixel offsets to center in the viewport
                var updatedCoordX = xCoord + offsetXValue;
                var updatedCoordY = yCoord + offsetYValue;

                // Create SVG elements
                var svgelement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                svgelement.setAttribute('id', sysData.name);
                svgelement.setAttribute('title', sysData.name);
                svgelement.setAttribute('class', 'system');
                svgelement.setAttribute('constellation-id', sysData.constellation_id);
                svgelement.setAttribute('style', 'margin-top:'+updatedCoordY+'px;margin-left:'+updatedCoordX+'px');
                svgelement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
                document.getElementById('container').appendChild(svgelement);
            } else {

            }
        });       
    });

    $(this.body).panzoom();
});

Functionality Explanation:

  • Iterates through a JSON object
  • Checks each object for matches containing the constellation_id
  • If match is found, adds coordinates to an array and stores the lowest coordinate values in variables
  • Creates an SVG element during each iteration

Challenge:

When creating the SVG elements, the CSS margins are set using coordX and coordY variables. I need to substitute these with the new offsetX and offsetY variables, but this doesn't work as the offsetX and offsetY values are not finalized yet due to the ongoing construction of arrayXCoords and arrayYCoords.

In essence, I have to establish the offsetX and offsetY variables first before proceeding with the SVG creation process.

Answer №1

In order to improve efficiency, this iteration can be divided into two separate loops: one for preparing data required for rendering, and another for actually rendering the SVG elements. This approach aligns well with the standard practice of separating rendering from state updates seen in frameworks like Flux and React, making it easier to transition to those systems in the future.

To earn extra points, consider avoiding the use of forEach and opting for functions without side effects. The library immutable.js is highly recommended for its functional-style utilities, immutable data structures, and support for equality checks (which are essential when using containers such as Lists and Maps).

Furthermore, I suggest switching to the use of let and const syntax, as well as incorporating arrow functions for improved code readability and efficiency.

Answer №2

Here is an example of how you can create the function using Array#filter, Array#map, a Set, spread syntax, arrow functions, and incorporating some jQuery for DOM manipulation:

$(function() {
    const systemsData = 'https://raw.githubusercontent.com/joeberthelot88/EVE-Online-Mapper/master/eveSystems.json?token=AWUj7mQ8T_6NBaRgIcz4Xz0KQd1SazMUks5ZjpeAwA%3D%3D';
    
    const importantConstellations = new Set([20000441, 20000442, 20000443, 20000444, 20000445, 20000446, 20000447]);

    $.getJSON(systemsData, function(data) {
        data = data.filter(sysData => importantConstellations.has(sysData.constellation_id));

        const xCoordValues = data.map(sysData => sysData.position.x / 100000000000000);
        const yCoordValues = data.map(sysData => sysData.position.y / 100000000000000);

        const offsetX = Math.min(...xCoordValues);
        const offsetY = Math.min(...yCoordValues);

        $('#container').append(
            data.map((sysData, i) => {
                const coordX = xCoordValues[i] + offsetX;
                const coordY = yCoordValues[i] + offsetY;

                const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                svgElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");

                return $(svgElement).attr({
                    id: sysData.name,
                    title: sysData.name,
                    "constellation-id": sysData.constellation_id,
                    "class": "system"
                }).css({ 
                    marginTop: coordY, 
                    marginLeft: coordX 
                });
            })
        );
    });

    $(this.body).panzoom();
});

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

Creating a Javascript countdown timer that does not involve displaying the

I stumbled upon this code on a website, but there's one tweak I'd like to make. Unfortunately, I can't seem to figure it out myself, so I'm reaching out for some help. What I want to achieve is removing the year from the date so that th ...

The mobile-responsive dropdown navigation bar functions well on browsers with small widths, but does not work properly on my phone

I am experiencing an issue with the mobile responsive dropdown navigation bar on my website. It works perfectly fine on a small width browser, but when I try to open it on my phone, nothing happens. This is puzzling me as I am new to making websites respon ...

Implementing autocompletion in an ASP.NET MVC4 application with AJAX and jQuery

I have been attempting to implement an autocomplete feature in a textbox that fetches company names. Despite successfully retrieving records and receiving them in the success function via Ajax, I am not seeing any suggested autocompletions in the textbox. ...

Insert two backslashes before a single backslash in PHP

I have been looking for a solution everywhere and have experimented with the JavaScript replace() function, str_replace, addslashes, and stripslashes, but I still can't seem to get the desired output. Here is what I am attempting: str_replace("&bsol ...

Javascript code for populating multiple objects with new items using a nested for loop

Trying to articulate my thoughts, I am interested in linking a list of skill sets to various individuals within their respective lists. For instance: I possess a Json object detailing individuals: "people": [ { "id": 1, "name": "Tony ...

After the completion of the JavaScript timer, the existing text remains in place even when the new text is displayed

https://jsfiddle.net/zLfuwdtu/1/ I've developed a script that tracks down to date 'Date1'. As it counts down, it shows the message "UNTIL FLOW." Once this timer reaches zero, another timer 'Date2' takes its place and displays "ON ...

Refreshing div content based on dropdown selection without reloading the page

I am currently working on implementing a dynamic dropdown feature that will update text content on a webpage without needing to refresh the entire page. The updated text will be fetched from a PHP function which receives input from the dropdown selection. ...

Having trouble transforming my JSON file into a JavaScript object

I have a JSON file with the following structure: { "branding": { "body": { "header_text_color": "#224466", "body_text_color": "##224466", "background_color": &quo ...

Slider Troubles - Strange glitch when reaching final slide

Currently, I am in the process of developing a basic slider for a website. Although it is still a work in progress and both the script and styling are unfinished, I have encountered an issue. After clicking on the next button, I am able to cycle through al ...

The error message "TypeError: event.preventDefault is not a function when using Formcarry with React Hook Form" is

How do I implement form validation using React Hook Form and Formcarry together? Something seems to be missing in my code or there might be a logic error Take a look at my code snippet: import { useForm } from "react-hook-form"; import { useFor ...

What could be causing certain javascript functions to not work properly?

Currently, I am using JavaScript and AJAX to validate a registration form. The functions restrict(elem) and checkusername() are both working as intended. When the AJAX passes the checkusername variable to PHP, it checks if the username exists and displays ...

Can the DOM be automatically refreshed after a set period of time without requiring any user input or triggers?

Is it possible to refresh the DOM using a function within a timeout without requiring an event trigger, such as a click? I have divs being inserted by Javascript that I cannot modify, and I need to loop through all of them with a specific class in order t ...

Automatic capitalization feature for input fields implemented with AngularJS

I have integrated a directive into my input field to validate a license key against a server-side API. While this functionality works well, I also want the license key to automatically add hyphens and appear in capital letters. For example, when a user in ...

Challenges arise when trying to import GLTFLoaders in THREE.js

I'm facing a couple of issues with implementing three.js on my WordPress page. First: I'm struggling to import GLTFLoader. When I try, I receive the error message: "Uncaught TypeError: Failed to resolve module specifier "THREE/examples/jsm/loade ...

The issue arises when attempting to update the input of a child component within a reactive form during the OnInit lifecycle

My dilemma arises in working with data stored in the ngrx entity store, as it gets displayed in chunks based on pagination. The issue lies with rxjs somehow remembering the paging history. For instance, when I fetch the first page of data from the server, ...

Experiencing a lack of defined or no outcome when outputting the API callback

I am troubleshooting an issue with my script that searches for movie titles from a database. While I receive results in the console without any errors, the renderMovies function is not storing the API movie title, plot, and other details properly in my var ...

Look into the data with vue.js, but there's not much

1. As a newcomer to vue.js, I encountered some surprising issues while experimenting with examples. The first one arose when I assigned an id to the body tag and included the following JavaScript code: <html> <head> <meta charset="utf-8 ...

What is the best way to show a table with 100% width in the Chrome browser?

I am currently working on debugging and expanding an express application that showcases a dataset through a series of nested tables on a webpage. Initially, all the CSS resided within style tags in the head section of the HTML file, and the tables were dis ...

Issue with the Styled Components Color Picker display

For the past 6 months, I have been using VSCode with React and Styled Components without any issues. However, recently I encountered a problem where the color picker would not show up when using CSS properties related to color. Usually, a quick reload or r ...