Leverage the variable from one function in a different function within Three.js using Javascript

After loading an obj file using three.js, I attempted to obtain the 'X' position of its vertices and save it in a variable named 'pos' inside the objloader function within the init() function. My goal was to access this variable's value in another function called displayposition(). However, when trying to do so, I encountered some difficulties.

var pos;

function init() {
    var objLoader = new THREE.OBJLoader();
    objLoader.load('objectfile.obj', function(object) {
        scene.add(object);
        pos = scene.children[5].children[0].geometry.attributes.position.getX(0);
        console.log(pos); //This successfully displays the vertex position value
    });
}

function displaypos() {
    console.log(pos); //Unfortunately, it does not display the vertex position value as expected
}

I am looking for a way to make the variable 'pos' global so that its value can be accessed and utilized throughout the program...

Answer №1

OBJLoader.load is a function that downloads and parses an OBJ file asynchronously. The time it takes for this process can vary, from instant to several seconds.

You mentioned calling init followed immediately by displaypos. Since these function calls happen sequentially, displaypos will be executed right after init finishes.

The sequence of events goes as follows:

  1. Initialize the global variable pos
  2. Define the function init
  3. Define the function displaypos
  4. Call the function init
    1. Assign objloader as a THREE.OBJLoader
    2. Set up the callback for objLoader.load
    3. Invoke objLoader.load <-- Note: This is asynchronous and might require some time
    4. init finishes executing because the call to objloader.load happens in sequence with a callback
  5. Call the function displaypos
    1. Log undefined to the console

A few moments later...

  1. The callback for objloader.load gets triggered
    1. Add object to scene
    2. Assign a value to pos
    3. console.log prints the correct value to the console

Therefore, your displaypos call does not display the value because it hasn't been set yet.

You have the option to add your own callback to init for the desired behavior or rewrite your code using Promise + async/await.

Callback approach

var pos;

function init(callback) {
    var objLoader = new THREE.OBJLoader();
    objLoader.load('objectfile.obj', function(object) {
        scene.add(object);
        pos = scene.children[5].children[0].geometry.attributes.position.getX(0);
        console.log(pos); //This displays the vertex position value
        callback(); // Points where execution exits
    });
}

function displaypos() {
    console.log(pos);
}

init(function(){
    displaypos(); // now shows the correct value
});

// Alternatively: init(displaypos);

Promise + async/await method

var pos;

async function init() {
    return new Promise(function(resolve){

        var objLoader = new THREE.OBJLoader();
        objLoader.load('objectfile.obj', function(object) {
            scene.add(object);
            pos = scene.children[5].children[0].geometry.attributes.position.getX(0);
            console.log(pos); //This displays the vertex position value
            resolve(); // Point where execution exits
        });

    });
}

function displaypos() {
    console.log(pos);
}

(async function(){
    await init();
    displaypos(); // displays the correct value
})();

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

Distinct elements within a JavaScript hash

Is there a jQuery method to add a hash into an array only if it is not already present? var someArray = [ {field_1 : "someValue_1", field_2 : "someValue_2"}, {field_1 : "someValue_3", field_2 : "someValue_4"}, {field_1 : "someValue ...

How to retrieve the value from a JSON object when the key is unknown in JavaScript

Here is the JSON file I'm working with: { "status": 200, "msg": "OK", "result": { "files": { "count": 1, "pUnJbKzql0f2": { "name": "How ...

What is the proper way to include "arr[i]" within a for loop?

How can I include "arr[i].length" in my FOR LOOP? Using arr[0].length works correctly, but when using just "i" it throws an error. My goal is to iterate through a 2D array. function calculateSum(arr) { var total = 0; for (let i = 0; i < arr[i] ...

Issue: The value of an object is not defined (evaluating '$scope.inputcode.password')

HTML Form: <form ng-submit="mylogin()"> <div class="list"> <label class="item item-input"> <span class="input-label">Username</span> <input type="text" ng-model="inputcode.username"> ...

The margin data table unexpectedly grew on its own following the action of toggling column visibility

The margin table data mysteriously increased on its own after hiding / showing columns. Here is the original result before show/hide column: https://i.sstatic.net/N96HX.png After multiple show/hide actions (more than 10 times): https://i.sstatic.net/lPIG ...

Exploring the creation of a dynamic graph with d3.js

I'm new to d3 and attempting to create a graph layout. var w = 1000; var h = 500; var dataset = { nodes: [{ name: 'Alice' }, { name: 'David' ...

Encountering a pair of errors while working with Node.js and Express

(Apologies for the vague title) I have been developing a project using Firebase and Express, but I am encountering some issues. src/index.js import { initializeApp } from "firebase/app"; import { doc, getFirestore } from "firebase/firesto ...

Angular implementation of checkboxes to streamline data filtering

I am currently displaying FreeEvents using a checkbox and passing the value to the filter as filter:filterFreeEvent, which is working perfectly fine. However, I would like to avoid passing the value in the filter and instead use a change event of a checkb ...

Set a value for the hidden field on the page using client-side scripting

When working with an ASP.net application, I often use Page.ClientScript.RegisterHiddenField("hf_Name", value). However, I am curious about how to override or set a new value for the same Hidden Field 'hf_Name' in the code behind. Can you provide ...

The filter functionality isn't functioning properly when attempting to filter an array of objects within a Vuex action

I have a collection of objects that is accessed through a getter. I am using this getter inside an action to filter the items, but no matter what I do, the filtering does not seem to work and it ends up returning all the mapped item IDs. filterItems({ gett ...

Issues with Semantic UI Calendar not displaying properly

I am currently experimenting with the Semantic UI Calendar, where there is a date input field and a calendar that pops up when selected as demonstrated in this initial example. Since I am not familiar with this process, I am uncertain if I have properly li ...

When inside a function declaration, io.socket is not defined, but it is defined outside of

Trying to utilize io.socket for a POST call to a controller action is presenting some unexpected behavior. Interestingly, when using io.socket.someMethod() within script tags as shown, it works smoothly: <script> io.socket.post('/visualization/ ...

Preventing Vue.js from triggering watch on initial load

I need to implement a feature where a button is initially disabled and only becomes enabled when the input value is changed. To achieve this, I am using a boolean flag that is set to true by default and turns false only when the input changes. The v-model ...

What strategies can I use to optimize the code for the function provided?

This function allows for the dynamic display of select tags for location selection based on employee designation. The current code functions correctly, but I believe it can be optimized further. // Function to activate different location options based on e ...

Tips on adding line breaks after periods that are not at the end of a sentence in HTML text nodes with regular expressions

Looking to craft a regex that can identify all periods not enclosed in quotes and not followed by a '<'. This is for the purpose of converting text into ssml (Speech Synthesis Markup Language). The regex will be utilized to automatically inse ...

A common inquiry regarding Vue: How to effectively incorporate fullpage.js wrapper with additional functionalities

Having recently delved into Vue, I am currently tackling a project that involves the Fullpage.js Vue wrapper. While I have successfully implemented the Fullpage functionality, integrating additional features like an animation-on-scroll function has proven ...

The file extension validation function is not functioning correctly on Windows, however it is successfully working as expected

async upload( @UploadedFile() file: Express.Multer.File, @Body() body: FileUploadDto, ) { const forbiddenExt = [ '.exe', '.bat', ]; const fileName = file.filename || f ...

Uncovering the origin of a problematic included file

When using Sencha Touch, it is common to encounter issues related to missing files. In most cases, simply including the file resolves the issue. However, there are instances where the problem lies in a faulty include, requiring you to locate where the file ...

The received URL from the POST request in React is now being opened

After completing an API call, I successfully received the correct response in my console. Is there a way to redirect my React app from the local host to the URL provided (in this case, the one labeled GatewayUrl under data)? Any assistance would be greatly ...

Unable to modify the active property of the specified object as it is read-only

Presented here is the interface: export interface ProductCommand extends ProductDetailsCommand { } This is the ProductDetailsCommand interface: export interface ProductDetailsCommand { id: string; active: boolean; archive: boolean; title: ...