Calling another function from a function

I have two Javascript functions. In my HTML I call the Setup function. I’m trying to call the Draw_Objects function from the Setup function. But every attempt I’ve made to call the Draw Objects function has failed. I hope someone can assist me.

function Setup () {
    
    var URL = 'http://localhost:8080/exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.json';
    var Rectangle_Object;
    var Rectangle_X_Coordinate;
    var Rectangle_Y_Coordinate;
    var Germanium_Object;
    var Germanium_X_Radius;
    var Germanium_Y_Radius;
    var Germanium_X_Center;
    var Germanium_Y_Center;
    var Set_Attributes;
    
    Set_Attributes = function Draw_Objects();
    
    fetch(URL)
        .then(res => res.json())
        .then(data => {
            console.log(data);           
            document.getElementById("Data_Text").value = data.Diagonal_Lines.Diagonal_Line_2.First_X1_Coordinate;
            document.getElementById("Data_Text").value = data.Diagonal_Lines.Base_Rectangle.Rectangle_Y_Coordinate;
            Rectangle_Object = document.getElementById('Base_Rectangle');
            Germanium_Object = document.getElementById('Germanium_Ellipse');
            Rectangle_X_Coordinate = JSON.stringify(data.Diagonal_Lines.Base_Rectangle.Rectangle_X_Coordinate);
            Rectangle_Y_Coordinate = JSON.stringify(data.Diagonal_Lines.Base_Rectangle.Rectangle_Y_Coordinate);
            Germanium_X_Radius = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Radius);
            Germanium_Y_Radius = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Radius);
            Germanium_X_Center = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Center);
            Germanium_Y_Center = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Center);
            function Draw_Objects(){}
            

           
        });
}
function Draw_Objects(){
    
            Rectangle_Object.setAttribute('x', Rectangle_X_Coordinate);
            Rectangle_Object.setAttribute('y', Rectangle_Y_Coordinate);
            Germanium_Object.setAttribute('rx', Germanium_X_Radius);
            Germanium_Object.setAttribute('ry', Germanium_Y_Radius);
            Germanium_Object.setAttribute('cx', Germanium_X_Center);
            Germanium_Object.setAttribute('cy', Germanium_Y_Center);
            Germanium_Object.style = "fill: #d5d5d7; stroke: black; stroke-width: 3;"
            document.getElementById("Data_Text").value = "x1 = " + Rectangle_X_Coordinate;
            
}

Delete:
Set_Attributes = function Draw_Objects();
(the data will not have been fetched)

At the end of the fetch code, edit:
function Draw_Objects(){}
to:
Draw_Objects();

1 Like

I think the computer is running the Draw_Objects function, but none of the values I stored in the Setup variables are transferring to the Draw_Objects function. How do I send the values to the Draw_Objects function?

function Setup () {
    
    var URL = 'http://localhost:8080/exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.json';
    var Rectangle_Object;
    var Rectangle_X_Coordinate;
    var Rectangle_Y_Coordinate;
    var Germanium_Object;
    var Germanium_X_Radius;
    var Germanium_Y_Radius;
    var Germanium_X_Center;
    var Germanium_Y_Center;
    var Set_Attributes;
    
    
    
    fetch(URL)
        .then(res => res.json())
        .then(data => {
            console.log(data);
            
            document.getElementById("Data_Text").value = data.Diagonal_Lines.Diagonal_Line_2.First_X1_Coordinate;
            document.getElementById("Data_Text").value = data.Diagonal_Lines.Base_Rectangle.Rectangle_Y_Coordinate;
            Rectangle_Object = document.getElementById('Base_Rectangle');
            Germanium_Object = document.getElementById('Germanium_Ellipse');
            Rectangle_X_Coordinate = JSON.stringify(data.Diagonal_Lines.Base_Rectangle.Rectangle_X_Coordinate);
            Rectangle_Y_Coordinate = JSON.stringify(data.Diagonal_Lines.Base_Rectangle.Rectangle_Y_Coordinate);
            Germanium_X_Radius = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Radius);
            Germanium_Y_Radius = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Radius);
            Germanium_X_Center = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Center);
            Germanium_Y_Center = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Center);
            Draw_Objects(Rectangle_X_Coordinate, Rectangle_Y_Coordinate);

            
        });
}

Within the fetch code you have console.log(data);. Do you see the JSON data in your browser’s console?

Your var statements such as var Rectangle_X_Coordinate; need to be declared outside the Setup() function so they become global variables and accessible within your Draw_Objects() function.

However a better approach would be to pass your data to the Draw_Objects() function like this:

fetch(URL)
    .then((res) => res.json())
    .then((data) => {
      console.log(data);
      Draw_Objects(data);
    });

The var declarations can then be deleted (except for URL).

Your function Draw_Data(); then needs to be declared with a parameter such as function Draw_Data(data);. You can then go from there to extract the individual coordinates etc within the Draw_Data function

3 Likes

If you are not console logging, you could lose the function wrapper e.g.
(data) => { Draw_object(data) }

And go for a leaner

fetch(URL)
    .then((res) => res.json())
    .then(Draw_Objects);

The res.json() response data will be passed straight to Draw_Objects instead.

2 Likes

This works:

function Setup() {
  fetch("germanium.json")
    .then((res) => res.json())
    .then(Draw_Objects);
}

function Draw_Objects(dimensions) {
  let base = document.getElementById("Base_Rectangle");
  let Ge = document.getElementById("Germanium_Ellipse");
  base.setAttribute('x', dimensions.Rectangle_X_Coordinate);
  base.setAttribute('y', dimensions.Rectangle_Y_Coordinate);
  Ge.setAttribute('rx', dimensions.Germanium_X_Radius);
  Ge.setAttribute('ry', dimensions.Germanium_Y_Radius);
  Ge.setAttribute('cx', dimensions.Germanium_X_Center);
  Ge.setAttribute('cy', dimensions.Germanium_Y_Center);
}

Setup();

Correction in post #4:
Draw_Data should read Draw_Objects.

I placed my global variables outside my functions. Then I rewrote my functions:

var Rectangle_X_Coordinate;
var URL = 'http://localhost:8080/exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.json';
var Rectangle_Object;
var Rectangle_Y_Coordinate;
var Germanium_Object;
var Germanium_X_Radius;
var Germanium_Y_Radius;
var Germanium_X_Center;
var Germanium_Y_Center;
var Set_Attributes;
function Store_Data() {
    
    fetch(URL)
        .then(res => res.json())
        .then(data => {
            console.log(data);
            document.getElementById("Data_Text").value = data.Diagonal_Lines.Diagonal_Line_2.First_X1_Coordinate;
            document.getElementById("Data_Text").value = data.Diagonal_Lines.Base_Rectangle.Rectangle_Y_Coordinate;
            Rectangle_Object = document.getElementById('Base_Rectangle');
            Germanium_Object = document.getElementById('Germanium_Ellipse');
            Rectangle_X_Coordinate = JSON.stringify(data.Diagonal_Lines.Base_Rectangle.Rectangle_X_Coordinate);
            Rectangle_Y_Coordinate = JSON.stringify(data.Diagonal_Lines.Base_Rectangle.Rectangle_Y_Coordinate);
            Germanium_X_Radius = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Radius);
            Germanium_Y_Radius = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Radius);
            Germanium_X_Center = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Center);
            Germanium_Y_Center = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Center);
            
        })
        .then(Draw_Objects());
}

function Draw_Objects(){
    
            Draw_Objects(Rectangle_X_Coordinate, Rectangle_Y_Coordinate);
            document.getElementById("Data_Text").value = Rectangle_X_Coordinate;
    
            Rectangle_Object.setAttribute('x', Rectangle_X_Coordinate);
            Rectangle_Object.setAttribute('y', Rectangle_Y_Coordinate);
            Germanium_Object.setAttribute('rx', Germanium_X_Radius);
            Germanium_Object.setAttribute('ry', Germanium_Y_Radius);
            Germanium_Object.setAttribute('cx', Germanium_X_Center);
            Germanium_Object.setAttribute('cy', Germanium_Y_Center);
            Germanium_Object.style = "fill: #d5d5d7; stroke: black; stroke-width: 3;"
            
            
}

This made the code easier to read, but it still doesn’t work. Why won’t the data transfer from the Store_Data function to the Draw_Objects function?

By the way, Archibald, I ran your code and generated a long list of errors. It started with an uncaught in promise rangeerror. I have no idea why this didn’t work. And yes I used my own http://localhost:8080/exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.json

My code is working on free webspace at:
http://create.mywebcommunity.org/germanium1.html

It does not work unless the .html and .json files are uploaded to a server.

1 Like

Also why would you be referencing localhost with an http header.

If you’re running the code locally to the files, http://localhost:8080/exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.json is just /exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.json, because you should already be on a page in the localhost:8080 server?

Firstly here is a grab of your code with eslint (Note: eslint has already done some fixing, in changing your ‘vars’ to ‘lets’)

Your use of snake_case, albeit it won’t break the code, in my mind is confusing.

A capital letter at the start of a function also indicates it is a constructor function e.g.

// captial 'R' in rectangle
function Rectangle(x, y) {
  this.x = x
  this.y = y
}

const myRectangle = new Rectangle(10, 5)
console.log(myRectangle) // {x: 10, y: 5}

I don’t understand why you keep overwriting this same value

document.getElementById("Data_Text").value = something

Is it just for you to visually log?

Draw_Objects will be run, before anything is fetched. It will be run immediately, and nothing is being passed into it.

.then(Draw_Objects());

If you want it to be invoked in the correct place, it shoudl be moved up into the above thenable e.g.

  ...
  Germanium_X_Center = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Center);
  Germanium_Y_Center = JSON.stringify(data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Center);
  Draw_Objects()
})

I’m also not sure why you are stringifying all those values

Then Draw_Objects

function Draw_Objects(){
    // this is a recursive call
    Draw_Objects(Rectangle_X_Coordinate, Rectangle_Y_Coordinate);
    document.getElementById("Data_Text").value = Rectangle_X_Coordinate;
    ...

The line

    Draw_Objects(Rectangle_X_Coordinate, Rectangle_Y_Coordinate);

Is a recursive call. It will call Draw_Objects recursively in a loop. The code below that line will never be run.

I would recommend you look at Archibald’s code again, and see if you can work from that.

2 Likes

I examined all of your ideas and I finally got something to work. Here is what I came up with:

let Retrieved_Data;
let Rectangle_Object;
let Rectangle_X_Coordinate;
let Rectangle_Y_Coordinate;
let Germanium_Object;
let Germanium_X_Radius;
let Germanium_Y_Radius;
let Germanium_X_Center;
let Germanium_Y_Center;
let My_URL;


function Retrieve_Data(){
    
        My_URL = 'http://localhost:8080/exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.json';
        fetch(My_URL)
             .then(res => res.json())
             .then(data => {console.log(data);
                Retrieved_Data = JSON.stringify(data);
                document.getElementById("Data_Text").value = Retrieved_Data;})
             .then(Store_Data)
             .then(Draw_Objects);
                  
    
}

function Store_Data() {
    
            document.getElementById("Data_Text").value = "I'm Here " + Retrieved_Data;
            Rectangle_Object = document.getElementById('Base_Rectangle');
            Germanium_Object = document.getElementById('Germanium_Ellipse');
            Retrieved_Data = JSON.parse(Retrieved_Data);
            Rectangle_X_Coordinate = Retrieved_Data.Diagonal_Lines.Base_Rectangle.Rectangle_X_Coordinate;
            Rectangle_Y_Coordinate = Retrieved_Data.Diagonal_Lines.Base_Rectangle.Rectangle_Y_Coordinate;
            Germanium_X_Radius = Retrieved_Data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Radius;
            Germanium_Y_Radius = Retrieved_Data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Radius;
            Germanium_X_Center = Retrieved_Data.Diagonal_Lines.Germanium_Ellipse.Germanium_X_Center;
            Germanium_Y_Center = Retrieved_Data.Diagonal_Lines.Germanium_Ellipse.Germanium_Y_Center;
            
            document.getElementById("Data_Text").value = "Now I'm Here " + Germanium_X_Radius;}
            
    


function Draw_Objects(){
            
            document.getElementById("Data_Text").value = Rectangle_X_Coordinate;
    
            Rectangle_Object.setAttribute('x', Rectangle_X_Coordinate);
            Rectangle_Object.setAttribute('y', Rectangle_Y_Coordinate);
            Germanium_Object.setAttribute('rx', Germanium_X_Radius);
            Germanium_Object.setAttribute('ry', Germanium_Y_Radius);
            Germanium_Object.setAttribute('cx', Germanium_X_Center);
            Germanium_Object.setAttribute('cy', Germanium_Y_Center);
            Germanium_Object.style = "fill: #d5d5d7; stroke: black; stroke-width: 3;"
            
            
}

I just have one last tiny problem. If you display the drawing the way it exists now, there are lines at the bottom of the batteries. I don’t want those lines to appear in my drawing. But I’m not sure how to get rid of those straight lines at the bottom of the batteries. Any ideas?

Duh I forgot. In order to solve the straight lines at the bottom of the batteries, you need my HTML code:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xs="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/1999/xhtml SVG_Bezier_Curve_Webpage_XML_Schema.xsd">
    <head>
         <title>SVG_Diagonal_Line</title>
         <link rel="stylesheet" type="text/css" href="http://localhost:8080/exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.css"/>
         <script language="javascript" src="http://localhost:8080/exist/rest/db/apps/HTML_Student/SVG_Diagonal_Line.js"/>
    </head>
    <body onload="Retrieve_Data()">
         <div id="Button_Box">
              <input type="text" id="Data_Text"/>
         </div>
         <div id="SVG_Position">
              <svg:svg id="My_SVG" height="500px" width="600px">
              <svg:line id="Diagonal_Line_1" x1="300px" x2="395px" y1="200px" y2="300px"/>
              <svg:line id="Diagonal_Line_2" x1="500px" x2="405px" y1="200px" y2="300px"/>
              <svg:rect id="Base_Rectangle"/>
              <svg:ellipse id="Germanium_Ellipse"/>
              <svg:ellipse id="Battery_1_Bottom" rx="20" ry="10" cx="250" cy="350" fill="green" stroke="black" stroke-width="3"/>
              <svg:rect id="Battery_1__Body" x="230px" y="300px" width="40px" height="50px" stroke="black" stroke-width="3" fill="green"/>
              <svg:ellipse id="Battery_1_Top" rx="20" ry="10" cx="250" cy="300" stroke="black" stroke-width="3"/>
              <svg:rect id="Battery_2_Body" x="530px" y="300px" width="40px" height="50px" stroke="black" stroke-width="3" fill="green"/>
              <svg:path id="Battery_2_Bottom" d="M 530,350 A 20,10 0,0,0 570,350" stroke="black" stroke-width="3" fill="green"/>
              <svg:ellipse id="Battery_2_Top" rx="20" ry="10" cx="550" cy="300" stroke="black" stroke-width="3"/>
              </svg:svg>
         </div>
    </body>
</html>