What is the best way to use Promise.all() to delay the return of an array that is currently being constructed within the function?

In the following code block, I am trying to set an array as the value for a local variable by calling a function that returns an array. The issue arises because the Promises in the second function are not resolved until after the array has been returned to the caller. I have attempted using Promise.all() on retArray without success. Upon running console.log() on my someobject object, the arrOfTitles field does not print out because the call to SkywalkerTitles() results in an empty array.

You can try out the code here.

Now the question is, how can I get someObject.arrOfTitles to retrieve the array of titles from SkywalkerTitles()?

function SkywalkerTitles(){
  let retArray = [];

  fetch('https://swapi.co/api/people/')
  .then(function(response){
    response.json()
    .then(function(result){
      return result.results[0];
    })
    .then(function(result){
       result.films.forEach(function(film){
        fetch(film)
        .then(function(response){
          response.json().then(function(result){
            console.log(result.title);
            retArray.push(result.title);
          });
        });
      })
      .catch(function(error){
        console.log(error)
      });
    });
  })
  .catch(function(error){
    console.log(error)
  });

}

function UseReturnedArray() {
  let someObject = { aThing: '', anotherThing: '', arrOfTitles: null };

  someObject.aThing = 'Thing One';
  someObject.anotherThing = 'Thing Two';
  someObject.arrOfTitles = SkywalkerTitles();

  console.log('Object With Returned Array:\n\n', JSON.stringify(someObject, null, 2));
}

UseReturnedArray();

Answer №1

Although @Svenskunganka's answer is comprehensive and valuable, in cases where async/await isn't supported in your environment and you prefer not to use a transpiler, this alternative approach may be more familiar if you already have some knowledge of Promises.

The main issue with your code is that SkywalkerTitles doesn't actually return anything; you mentioned it returns an empty array, but there is no return statement, so the returned value is undefined.

I've also eliminated the .catch block because placing it where you had it could lead to problems - handling rejections in one place is usually sufficient instead of scattering them throughout the code.

function SkywalkerTitles() {
    return fetch('https://swapi.co/api/people/').then(function (response) {
        return response.json();
    }).then(function (result) {
        return result.results[0];
    }).then(function (result) {
        return Promise.all(result.films.map(function (film) {
            return fetch(film).then(function (response) {
                return response.json();
            }).then(function (result) {
                return result.title;
            });
        }));
    });
}

function UseReturnedArray() {
    SkywalkerTitles().then(function (arrOfTitles) {
        var someObject = {
            aThing: '',
            anotherThing: '',
            arrOfTitles: arrOfTitles
        };
        console.log('Object With Returned Array:\n\n', JSON.stringify(someObject, null, 2));
    }).catch(function(reason) {
        console.log(reason);
    });
}
UseReturnedArray();

Notice the flattened promise chain compared to yours, as well as the use of Array#map instead of Array#forEach + Array#push.

Answer №2

Utilizing async/await can greatly enhance the clarity and organization of your code:

async function getJediTitles () {
  let character = await fetch('https://swapi.co/api/people/').then(res => res.json()).then(res => res.results[0])
  return await Promise.all(character.films.map(async (film) => {
    return await fetch(film).then(res => res.json()).then(res => res.title)
  }))
}

async function displayJediTitles () {
  try {
    let jediInfo = {
      name: '',
      rank: '',
      titles: await getJediTitles()
    }

    console.log(jediInfo)
  } catch (error) {
    console.error(error)
  }
}

displayJediTitles()

Check out https://repl.it/Fd94/8

If this seems unfamiliar, it might be worthwhile to explore how async/await and Promise complement each other.

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

What methods can I employ in Javascript to automatically display search results obtained from multiple HTTP search queries?

In my tampermonkey script, I am attempting to process an array of names by performing a search and printing the page for each one. The script runs automatically upon loading the page, hence the necessity of the if statement. $(document).ready(function(){ ...

Generate a Calendar Table using JavaScript in the Document Object Model (DOM

I have set up a table with 6 rows and 5 columns. The purpose of the table is to represent each month, which may have varying numbers of days. I want each column to display dates ranging from 1-30 or 1-31, depending on the specific month. Here's what ...

What is the best way to pass the value from one textfield to another using material UI in a react application?

I'm looking to transfer the content from a text field in a dialog window to another text field that is not embedded. However, instead of transferring the actual text field value, I'm getting an output of "object Object". Can you help me figure ou ...

Utilizing a function as an argument in another function (with specified parameters)

I’m stuck and can’t seem to solve this problem. In my function, the parameter filter needs to be a function call that accepts an object created within the same function: function bindSlider(time, filter) { var values = { min : 8, max : ...

I am looking to create a PHP script that restricts access to individuals under the age of 18 based on the current

I'm looking for a way to use Php, javascript, or ajax to restrict access for individuals under 18 years old based on the current date. Any suggestions on how I can achieve this? Could someone please review my code for calculating age onblur or onSubm ...

When clicking on HTML input fields, they do not receive focus

I am facing a puzzling issue where I am unable to access the input fields and textareas on my HTML form. The JS, HTML, and CSS files are too large for me to share here. Could someone provide guidance on what steps to take when troubleshooting this unusual ...

Tips for successfully retrieving a variable from a function triggered by onreadystatechange=function()

Combining the ajax technique with php, I'm looking to extract the return variable from the function called by onreadystatechange. A java function triggers a call to a php script upon submission, which then validates certain data in the database and r ...

Experience the combined power of addthis, isotope, and nicescroll - all in a single

I am utilizing a WordPress template that includes a set of share buttons from AddThis. <ul class="addthis extra"> <li class="addthis-hold"> <div class="addthis_toolbox" addthis:url="<?php the_permalink( ...

To prevent the need for redundant iterations, arrange an object based on a specific field

Looking for a way to avoid repeating the same loop multiple times while sorting an object efficiently. Take a look at this sample object: movies = [ { title: "The Lord of the Rings: The Fellowship of the Ring" year: 2001 ...

Vue.js computed property fails to initiate

Why is the Vue JS computed property not triggered with this markup? <!-- language: lang-html --> <p>£{{plant_price}}</p> <div v-if="selected.plant.variations.length > 0 "> <select v-model="selected.plant.selected_ ...

What are the steps to utilize the `<script setup>` feature?

Vue version: 3.0.11 Here is the code snippet: <template> <button @click="inc">{{ count }}</button> </template> <script setup> import { ref } from 'vue' export const count = ref(0) export const i ...

What is the best way to create a fixed footer in Next.js using React?

I'm looking to create a fixed footer that will stay at the bottom of the page if there isn't enough content to fill it. I've been researching ways to achieve this using CSS, but many of the methods don't easily translate to React/Next.j ...

Synchronous execution in Node.js: Best practices for coordinating tasks

While Node.js is known for its asynchronous nature, I am seeking to perform tasks in a sequential manner as outlined below: 1. Make an API request > 2. Convert the body from XML to JSON.stringify format > 3. Pass the string to a template. request.g ...

The Cross-Origin Resource Sharing request using the PUT method has been denied due to restrictions set by the

I am currently using CORS requests to communicate between my client and server located on different domains. I have configured my Apache HTTP server to use SSL in the following manner: // Utilizing AJAX withCredentials=true (sending cookies, allowing SSL ...

Is there a way to point my Github URL to the index file within a specific folder?

The actual working location of my website: My desired working location for the site: Originally, I had my index.html file in the main repository, but later moved it to an html folder along with other html files for better organization. How can I ensure t ...

The received data object appears to be currently undefined

I am currently using MapBox to display multiple coordinates on a map, but I am encountering an issue where the longitude and latitude values in my return object are showing up as undefined. Could there be a missing configuration that is preventing the data ...

Retrieving form elements in Angular

I need to extract the element name and class from a form passed to a function. Is there a way to accomplish this? On the HTML side: <form name="test"> <div> <input type="text" class="test1" name="test2"/> </div> ...

Utilize an asynchronous method to upload files to Google Cloud Storage in a loop

I am new to using Javascript and have been working on a loop to upload images to Google Cloud Storage. While the image uploads correctly with this code, I'm facing an issue where the path (URL) is not being saved in the database AFTER the upload. I a ...

Expanding worldwide mixin in Nuxt.js

Currently, I am working with Nuxtjs version 2.15.7 and have a mixin file structured like this: utils.js : import Vue from "vue" if (!Vue.__utils__) { Vue.__utils__ = true Vue.mixin({ data(){ return{ ... } }, ...

Guide on securely presenting an HTTP-only cookie as a bearer token, without the use of Angular.JS

Can a JWT be securely stored as an HTTP-only cookie and also used as a bearer token without relying on Angular.JS? I believe this could be achievable, as Angular.JS offers similar features (although I'm not sure if they use an HTTP-only cookie to sto ...