.then() failing to wait for completion of all promises

Currently, I am loading multiple gltf models using an async function. After that, I go through the results using .then() and add the models to my scene. However, everything works perfectly fine until I decide to remove one of the models from the source. Specifically, when the model I want to remove is larger than the rest. Upon removing the model, it appears as though the promise resolution isn't waiting for all promises to resolve before calling .then(). Here is the loader function, can you spot what I might be doing wrong?

The 'source' mentioned here is simply an array of objects containing paths to various model files.

The issue seems to lie within the .then() block. The error message displayed in the console states: 'variant.components is not iterable' whenever a large-sized model is removed from the 'source' array.

async function modelLoader(source, loadingManager) {
    const gltfLoader = new GLTFLoader(loadingManager);
    const promises = [];
    for (let i = 0; i < source.length; i++) {
      promises.push(
        new Promise((resolve) => {
          const model = {}
          gltfLoader.load(source[i].file, (gltf) => {
            const children = [...gltf.scene.children];
            console.log(children);
              model.components = children;
            resolve(model);
          });
          if (source[i].type === 'baseModel' || (source[i].type === 'variant' && source[i].viewPoints.file !== 'none')) {
            gltfLoader.load(source[i].viewPoints.file, (gltf) => {
              const viewPoints = [...gltf.scene.children];
                model.viewPoints = viewPoints;
              resolve(model);
            });
          } else if (source[i].type === 'baseModel' || (source[i].type === 'variant' && source[i].viewPoints.file === 'none')) {
            model.viewPoints = 'none';
          } else if (source[i].type === 'land') {
            gltfLoader.load(source[i].buildingLine, (gltf) => {
              const buildingLine = [...gltf.scene.children]
              model.buildingLine = buildingLine
              resolve(model)
            })
          }
        })
      );
    }
    return await Promise.all(promises);
  }



const allModels = modelLoader(source, loadingManager)

allModels.then(result => {
    for (const variant of result) {
        if (variant.type === 'baseModel') {
            const house = new THREE.Group()
            for (const components of variant.components) {
                house.add(components)
            }       
        }                       
    }
})     

Answer №1

If you happen to encounter the same problem, I have discovered a solution - using await for each call of the gltfLoader resolves the issue.

  async function modelLoader(source, loadingManager) {
const gltfLoader = new GLTFLoader(loadingManager);
const models = [];

for (let i = 0; i < source.length; i++) {
  const model = {
    name: source[i].name,
    type: source[i].type,
    isDefault: source[i].isDefault,
    section: source[i].section,
    isDetached: source[i].isDetached,
    isInterior: source[i].isInterior,
    price: source[i].price,
    image: source[i].image,
  };

  const gltf = await new Promise((resolve) => {
    gltfLoader.load(source[i].file, (gltf) => {
      resolve(gltf);
    });
  });

  const children = [...gltf.scene.children];
  model.components = children;

  if (
    source[i].type === 'baseModel' ||
    (source[i].type === 'variant' && source[i].viewPoints.file !== 'none')
  ) {
    const viewPointsGltf = await new Promise((resolve) => {
      gltfLoader.load(source[i].viewPoints.file, (gltf) => {
        resolve(gltf);
      });
    });

    const viewPoints = [...viewPointsGltf.scene.children];
    model.viewPoints = viewPoints;
  } else if (
    source[i].type === 'baseModel' ||
    (source[i].type === 'variant' && s...

}

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

Tips for connecting a DOM element when a link is clicked

I am currently browsing http://localhost:8000/index.html My goal is to navigate to localhost:8006/someAddress and interact with an element with the id '157579' as well as click on a button with the id '1787' that will trigger a change ...

Transferring PHP and JavaScript variables via AJAX to PHP page and storing in MySQL database table

After searching through numerous similar questions, I still haven't found the exact answer I need. I have a set of js variables that are sent via ajax to a location.php file, where they will be inserted into a mysql table. The current ajax call looks ...

Using React Native to implement Firebase onSnapshot with FlatList pagination

INTRODUCTION I have a collection of items stored in FireStore with the "date" property. On the client side, I'm using a FlatList to display these items ordered by date, starting with the most recent item at the top. The challenge I'm facing is ...

Transforming the typical click search into an instantaneous search experience with the power of Partial

I am working on a form that, when the user clicks a button, will display search results based on the entered searchString. @using (Html.BeginForm("Index", "Search")) { <div id="search" class="input-group"> @Html.TextBox("searchString", n ...

"Exploring the Power of Vue 3 Event Bus Through the Composition API

I recently set up mitt and I'm facing difficulties dispatching events to another component. The issue arises due to the absence of this in the setup() method, making it challenging to access the app instance. Here's my current approach: import A ...

Trigger the submission of Rails form upon a change in the selected value within a dropdown form

I am working on a Rails application that has a table of leads. Within one of the columns, I display the lead's status in a drop-down menu. My goal is to allow users to change the lead's status by simply selecting a different value from the drop-d ...

Is there a way for me to receive numerical values instead of NaN?

I'm currently facing a challenge in creating a Fibonacci number generator and I've hit a roadblock. It seems like I have a solution, but the appearance of NaN's is causing me some trouble. function fibonacciGenerator (n) { var output = [ ...

The automatic counter is exhibiting some surprising behavior

I have two different sets of code snippets, presented below. The initial one is a clock that displays the current time and updates every second. It functions flawlessly! The second piece of code is quite similar to the first, except that instead of showi ...

Creating Visuals from Text with ReactJS/NextJS

Looking to transform text into an image with a shareable link in ReactJS, similar to Spotify's lyrics sharing feature. I haven't attempted any solutions so far. I've explored various libraries without success. ...

Achieving Ajax Request Activation through Button Click in Bootstrap

I am currently working on a modal form using Bootstrap that allows users to customize a specific item before adding it to the cart. My issue is that the "Add to Cart" button does not trigger the Ajax request as intended. I have followed a modified version ...

Is there a way to retrieve data from a sealed JSON object using JavaScript?

The data is being fetched from the API and here is the response object: { "abc": [{ "xyz": "INFO 1", "pqr": "INFO 2" }, { "xyz": "INFO 3", "pqr": "INFO 4" } ] } We are lookin ...

Bootstrap / Blazor - no action when clicking on an image link

Having issues with adding a simple HTML link around an image in my Bootstrap 4.5 / Blazor app. When I click on the link, nothing happens. How is this possible? I've tried using the <a href"..."><img ...> pattern, as well as NavL ...

Is there a way for me to enable autoplay on the Slice Slider?

I'm struggling to enable autoplay on a slider I have here. Is it possible to quickly set this up in the var settings? I attempted to insert the setInterval(spin, 3000); command before and after the init lines, but it hasn't been successful so fa ...

Substitute the Iframe element with Ajax technology

Currently, I am working on a project where I want to include previews of various websites within my own website. Right now, I am using Iframes to load the website previews and allow users to interact with them. For SEO purposes, I have decided to replace ...

Grouping Elements in JavaScript with a Personalized Sorting Algorithm

As I work with Objects in Javascript, my goal is to sort them by clustering based on their distances from each other. In Java, I have successfully achieved this using a custom distance function and hierarchical clustering. Unfortunately, I haven't be ...

Tips for adding a numerical prefix to each line when the textarea is in editable mode

After conducting extensive research on Google, I have been unable to find a satisfactory solution. What I am aiming for is similar to the concept illustrated in this image: https://i.sstatic.net/iq6DE.png I should mention that my current technology stack ...

Combining the Powers of ExpressJS and MeteorJS

I am currently using an Epress JS rest api to send data to a MongoDB database. I'm curious if it's feasible to incorporate Meteor JS for fetching these values from the MongoDB. Any insights or suggestions would be greatly valued. Thank you ...

What is the best way for an object to recognize if its value matches a key in another object, and then retrieve that value

Is there a way to make an object detect if its value is equal to another object's key and then retrieve it? Let's consider the following object named: AnswerString let AnswerString ={ 0: "B", 1: "x" } and the answers are in different objects, ...

Utilizing regular expressions to search through a .md file in JavaScript/TS and returning null

I am currently using fs in JavaScript to read through a changelog.MD file. Here is the code snippet: const readFile = async (fileName: string) => { return promisify(fs.readFile)(filePath, 'utf8'); } Now I am reading my .md file with this fu ...

What is the best way to create fading text effects in an AngularJS application?

Running an AngularJS web application that showcases three words for 5 seconds each: Hello, World & Goodbye. The controller setup is as follows: self.currentIndex = 0; self.myTexts = ['Hello', 'World', 'Goodbye']; self.cu ...