0

I create an array in a VueX action that I, in one case, commit to the VueX state (and then use getter to assign it), and in another case, deliver the array in a promise. There seems to be a difference in the type or form of the arrays, even though they stem from exactly the same array.

The VueX getter probably assigns the array correctly whereas just delivering the array as a promise does not.

For the array where reduce is working (VueX getter assigned), logging the array to the console gives:

Array(3) [ {…}, {…}, {…} ]

And when I open it:

0: Object { track: Getter & Setter, course: Getter & Setter, courseLevel: Getter & Setter, … }
​
1: Object { track: Getter & Setter, course: Getter & Setter, courseLevel: Getter & Setter, … }
​
2: Object { track: Getter & Setter, course: Getter & Setter, courseLevel: Getter & Setter, … }
​
__ob__: Object { value: (3) […], dep: {…}, vmCount: 0 }
​
length: 3
​
<prototype>: Object { … }

The array where reduce is not working in the console:

Array []

and opened:

0: Object { track: "test", course: "test", courseLevel: "Beginner", … }
​
1: Object { track: "Computer Vision", course: "advanced openCV", courseLevel: "Advanced", … }
​
2: Object { track: "Computer Vision", course: "intro to comp vis", courseLevel: "Beginner", … }
​
length: 3
​
<prototype>: Array []

There are some differences and I can't figure out where it comes from.

The array comes from the same object, with the first (working) one pushed to VueX state, then loaded again with a getter, and the second (not working) pushed as a promise.

How do I push an array as a promise such that it has the <prototype>: Object { ... } and Getter & Setter property on all values?

EDIT:

The action that gets dispatched and returns the promise

loadSelfCourses ({ commit, getters }, payload) {
      return new Promise((resolve, reject) => {
        var uemail = ''
        if (payload.commitToState) {
          commit('clearSelfCourses')
          uemail = getters.user.email
        } else {
          uemail = payload.email
        }
        firebase.firestore().collection('userCourses').doc(uemail).collection('userSelfCourses').get()
          .then(
            querySnapshot => {
              var tempSelfCourses = []
              querySnapshot.docs.forEach(doc => {
                firebase.firestore().collection('selfCourses').doc(doc.id).get()
                  .then(
                    promise => {
                      const data = promise.data()
                      const currentCourse = {
                        track: data.track,
                        course: data.course,
                        courseLevel: data.courseLevel,
                        learningGoal: data.learningGoal,
                        link: data.link,
                        hoursRequired: data.hoursRequired,
                        courseID: doc.id,
                        creatorID: data.creatorID,
                        registeredUsers: data.registeredUsers,
                        startDate: doc.data().startDate,
                        endDate: doc.data().endDate,
                        status: doc.data().status
                      }
                      tempSelfCourses.push(currentCourse)
                    }
                  )
              })
              if (payload.commitToState) {
                commit('setSelfCourses', tempSelfCourses)
              } else {
                resolve(tempSelfCourses)
              }
            })
          .catch(error => {
            reject(error)
            commit('setLoading', false)
          })
      })
    },

Code that dispatches the action and receives the promise.

this.$store.dispatch('loadListOfUsersForAdmin', { email: this.$store.getters.user.email }).then(data => {
      data.forEach(user => {
        this.$store.dispatch('loadSelfCourses', { email: user, commitToState: false }).then(loadedCourses => {
          const progress = this.allCourseProgress((loadedCourses))
          // do some stuff here
        })
      })
    })
CertainPerformance
  • 260,466
  • 31
  • 181
  • 209
Joram
  • 83
  • 9
  • Your second array is populated asynchronously. Figure out where it's populated. You may need a `Promise.all` to wait for all asynchronous actions to resolve – CertainPerformance Feb 10 '20 at 10:24
  • @CertainPerformance Yes the array that I commit and deliver as a promise is populated asynchronously. And the commit/deliver happens at the same time. Is there a way to change it so that it has the first array form? Committing and getting is not a viable option for me here. – Joram Feb 10 '20 at 10:34
  • @CertainPerformance My question does not have answers in the other thread, can you remove that? I don't care how it is showing in the console, the reduce function does not work on the second array but does on the first. And it's not because the array is still changing when I call the reduce. It is delivered as a promise after it is completely generated. – Joram Feb 10 '20 at 10:53
  • See the other canonical for this sort of thing - link at the top. Can you post the code that creates the array? – CertainPerformance Feb 10 '20 at 11:32
  • @CertainPerformance I posted the code that dispatches the action (and receives the promise) and the action. The `allCourseProgress` method does the reduce. No idea why the `tempSelfCourses` that I resolve can't be reduced in the `allCourseProgress`. The exact same method can reduce it from the $store.getters – Joram Feb 10 '20 at 12:43
  • I rolled back to the revision which contains the code necessary to understand what's going on. See https://stackoverflow.com/questions/31426740/how-to-return-many-promises-in-a-loop-and-wait-for-them-all-to-do-other-stuff - don't use `forEach`, use `.map` to construct a new array of Promises. Then you can call `Promise.all` on that array. (it would also be good to avoid the [explicit Promise construction antipattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) – CertainPerformance Feb 10 '20 at 22:12

0 Answers0