What causes Promise.all to misbehave in mapping an array?

I've been using Vue and attempting to make some axios requests within a map method over an array, but I'm getting unexpected results.

Here's my function:

  async getFavoriteRecipes(){
           try{
            let myRecipes=[]
            const response = await this.axios.get("https://david-matan-recipe-api-server.herokuapp.com/api/profiles/myprofile")
            let myFavoritedIds=response.data.favoriteRecipe;
            myRecipes= await Promise.all(myFavoritedIds.map(async (recipeInfo) =>{
                if(id.type==="spooncalur"){
                    const result = await this.axios.get("https://david-matan-recipe-api-server.herokuapp.com/api/recipes/"+recipeInfo.id)
                    myRecipes.push(result.data)
                    return myRecipes
                }
                else{
                    const result = (await this.axios.get("https://david-matan-recipe-api-server.herokuapp.com/api/recipes/userecipe/"+recipeInfo.id))
                    myRecipes.push(result.data)
                    return myRecipes
                }    
             }
            ))
            this.myFavoriteRecipe=myRecipes
           }
           catch(err)
           {
             if(err.response.status==='401'){
                 this.$root.store.username=undefined
                 this.$router.push('/login')
             }
              console.log(err.response)
           }
        }

I was expecting to receive an array of 6 JSON objects, but instead, I'm getting an array of 6 arrays with the same 6 JSON objects inside each one. Can anyone shed some light on why this is happening?

Answer №1

It appears that you are interested in storing an array of data from each request result. In this case, I recommend returning the data instead of pushing it to the myRecipes array. By doing so, the data will automatically be added or replaced in the list. Here is how the updated code would look:

async getFavoriteRecipes() {
    try {
        let myRecipes = []
        const response = await this.axios.get("https://david-matan-recipe-api-server.herokuapp.com/api/profiles/myprofile")
        let myFavoritedIds = response.data.favoriteRecipe;
        myRecipes = await Promise.all(myFavoritedIds.map(async (recipeInfo) => {
            if (id.type === "spooncalur") {
                const result = await this.axios.get("https://david-matan-recipe-api-server.herokuapp.com/api/recipes/" + recipeInfo.id)
                return result.data
            } else {
                const result = (await this.axios.get("https://david-matan-recipe-api-server.herokuapp.com/api/recipes/userecipe/" + recipeInfo.id))
                return result.data
            }
        }))
        this.myFavoriteRecipe = myRecipes
    } catch (err) {
        if (err.response.status === '401') {
            this.$root.store.username = undefined
            this.$router.push('/login')
        }
        console.log(err.response)
    }
}

If you need help understanding the map function, you can refer to these resources: https://www.youtube.com/watch?v=DC471a9qrU4 or https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Answer №2

The issue has already been clarified by Ayk, however, the code can also be simplified to:

const url = "https://steve-jones-recipe-site.herokuapp.com/api/recipes/" + 
  id.type==="spooncalur" ? '' : 'usersselection/'
  
myRecipes = await Promise.all(mySavedIds.map(recipeData =>
  this.fetchData(url + recipeData.id)
))

There is no necessity to mark

this.fetchData(url + recipeData.id)
as asynchronous as Promise.all expects an array of promises as input, not resolved values

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

Is your Angularjs code failing to execute properly?

I have a simple code setup, but for some reason my Angularjs code isn't running as expected. Here is the snippet of my html code: <html> <head> <title></title> </head> <body ng-app="myAppApp"> <div ng-contr ...

retrieve JSON object from deferred response of AJAX request

After utilizing Ajax to send an item to a SharePoint list, I aim to incorporate the jsonObject received in response into a list of items. Located in AppController.js $scope.addListItem = function(listItem){ $.when(SharePointJSOMService.addListIte ...

Node JS post route experiencing issues with updating variables within function

I'm in the process of developing an online salon booking system. My goal is to prevent a booking from being made if the salon already has an appointment booked for that day and if the user attempting to make the booking also has an appointment booked ...

Display text when hovered over or clicked to insert into an HTML table

I have an HTML table connected with a component field gameArray and I need it to: Show 'H' when the user's cursor hovers over TD (:hover) and the corresponding field in gameArray is an empty string, Fill the gameArray field after a click. ...

Issue with updating bookmark symbol after delete, experiencing error 500 in AJAX on Rails

Seems like the bookmark is being destroyed, but there's a problem causing an error 500 in the console and preventing the bookmark from being unselected. This issue arises when I update the page, indicating that it is indeed being destroyed, but for so ...

Parent passing down React state, but child component fails to update it

When a setState function is passed down from a parent component, I aim to update the state of the parent setter if the enter key is pressed. However, despite setting the state, nothing seems to happen and I am left with an empty array. Below is the snippe ...

What is the best way to retrieve the document DOM object within an EJS template?

I am attempting to display a list of participants when the user clicks on the button. However, every time I try, I encounter an error stating "document is not defined". (Please refrain from suggesting the use of jQuery!). <% var btn = document.getEle ...

Module not discovered by nodeJS within the current directory

In my node application, I am trying to incorporate a module called dishRouter. The file structure looks like this :- Structure The dishRouter is exported from Dishes/index.js and imported into my app.js using the following code: var dishRouter = re ...

Optimizing performance with ng-if for 500 watchers

When repeating data with ng repeat, I encountered an issue where some of the data.image (src) values were null and I did not want them to be included in the repeat process. To solve this issue, I implemented a simple ng-if statement. <div ng-repeat="d ...

Tips for incorporating Vue's v-model with Bootstrap's button-group radios

Currently, I am working on adapting vuejs with bootstrap 4.4 where I intend to refactor the code by transitioning from invoking methods to utilizing v-model (some bootstrap markup has been excluded for clarity). The radio button group design is inspired by ...

Performing numerous asynchronous MongoDB queries in Node.js

Is there a better way to write multiple queries in succession? For example: Space.findOne({ _id: id }, function(err, space) { User.findOne({ user_id: userid }, function(err, user) { res.json({ space: space, user: user}); }); }); It can g ...

How can API calls be efficiently made in React?

While working in React, I encountered a minor issue when calling the API because the ComponentWillMount method is deprecated. Here is what I did: class MyClass extends Component { constructor() { super(); this.state = { questionsAnswers: [ ...

Tips for updating the content of a div with fresh data using a slideshow effect in jQuery

Imagine you have a div called A and an array filled with text data. When t=0, div A will display $data[0]. Then, after every n seconds, I want the div to show the next piece of data in the array. I am interested in creating a transition effect similar to ...

Phonegap app developer encounters issue with sending ajax requests

Recently, I encountered an issue with Ajax in my Phonegap development. Previously, it worked perfectly but now when I call the Ajax function, nothing happens. Here are the steps I have taken to troubleshoot: 1) I edited the config.xml file and added the f ...

React Native App experiences immediate crashes when launched on TestFlight

I've encountered a frustrating issue with my application that keeps crashing when loaded into Testflight. To troubleshoot, I decided to start from scratch and created a basic expo react native application to pinpoint the source of the problem. After ...

Using Vue.js to pass a variable from a parent component to a child component

Parent component: ShowComment Child component: EditComment I'm attempting to pass the value stored in this.CommentRecID to the child component. In the template of ShowComment, I have included: <EditComment CommentRecID="this.CommentRecID" v-if= ...

Icon fonts are not compatible with AngularJS, causing difficulties in their usage together

Incorporating icon fonts from Icomoon in my AngularJS framework project has been a challenge. Due to Strict Contextual Escaping (SCE), I am unable to properly generate these icons, resulting in the display of HTML number codes like "&#xe006;" instead o ...

Convert the value of a Javascript variable into a PHP variable

I am feeling confused about how to pass JavaScript variables to PHP variables. Currently, I have a PHP session named example_survey and three buttons with jQuery attributes. When a button is clicked, it triggers a jQuery click event and passes the attribut ...

Presenting a trio of distinct tables each accompanied by its own unique button option

I am attempting to create a functionality where there are 3 buttons and when a user clicks on one of them, it shows the corresponding table while hiding the other two. I have experimented with using getElementById to manipulate the display property of the ...

automatically assign a default value to the data-html5 attribute

There is a small code snippet that applies a preset style to a div with custom attributes. These attributes set the src and an APA text to an img tag, as well as generate a button with zoom option using FancyBox. As someone new to jQuery, I might be misusi ...