Areg
Areg

Reputation: 1485

Uncaught (in promise) TypeError: undefined is not a function (Vue.js, Electron)

i am trying to animate some elements using anime.js with some promise functions, the problem is that the second function wont run once the previous one was successful.

<script>
import Splash from '../components/Splash.vue';
import Intro from '../components/Intro.vue';

export default {
  components: {
    Splash,
    Intro,
  },
  mounted() {
  //This is the line of the error `const animateSplash = async () => {` 
    const animateSplash = async () => {
      const splashAnim = this.$anime({
        targets: '.logo',
        easing: 'cubicBezier(.5, .05, .1, .3)',
        keyframes: [
          { duration: 1000, opacity: 0 },
          { duration: 1000, opacity: 1 },
          { delay: 3000, duration: 500, opacity: 0 },
        ],
        complete(anim) {
          document.querySelector('.logo-wrapper').style.display = 'none';
        },
      }).finished;

      await Promise.all(splashAnim);
    };

    animateSplash().then(() => {
      const introAnim = this.$anime({
        targets: '.intro-wrapper',
        easing: 'cubicBezier(.5, .05, .1, .3)',
        keyframes: [
          { duration: 1000, opacity: 0 },
          { duration: 1000, opacity: 1 },
        ],
        begin(anim) {
          document.querySelector('.intro-wrapper').style.display = 'flex';
        },
      }).finished;
    });
  },
};
</script>

I am getting an error

Home.vue?76f2:17 Uncaught (in promise) TypeError: undefined is not a function which again points to const animateSplash = async () => {. But it runs the first animation which is splashAnim.

Upvotes: 0

Views: 2422

Answers (2)

Roamer-1888
Roamer-1888

Reputation: 19288

A few points:

  1. Promise.all() accepts Array. splashAnim appears not to be Array. (as already acknowledged)
  2. If splashAnim is Promise (or even just a thenable), then simply return splashAnim;.
  3. If you are dealing with Promises, you can (and arguable should) avoid those cumbersome begin and complete callbacks.

As far as I can tell (and assuming that this.$anime().finished does indeed return Promise), you are trying to do as follows:

export default {
    components: { Splash, Intro },
    mounted() {
        return this.$anime({
            'targets': '.logo',
            'easing': 'cubicBezier(.5, .05, .1, .3)',
            'keyframes': [
                { 'duration': 1000, 'opacity': 0 },
                { 'duration': 1000, 'opacity': 1 },
                { 'delay': 3000, 'duration': 500, 'opacity': 0 }
            ]
        }).finished
        .then(() => {
            document.querySelector('.logo-wrapper').style.display = 'none';
            document.querySelector('.intro-wrapper').style.display = 'flex';
            return this.$anime({
                'targets': '.intro-wrapper',
                'easing': 'cubicBezier(.5, .05, .1, .3)',
                'keyframes': [
                    { 'duration': 1000, 'opacity': 0 },
                    { 'duration': 1000, 'opacity': 1 },
                ]
            }).finished;
        });
    }
};

Note that the two return statements allow the caller of mounted() to be informed, by way of Promise, of completion of the whole animation process.

Upvotes: 1

Areg
Areg

Reputation: 1485

It turns out the problem was this one line which awaited for the promise

await Promise.all(splashAnim);

I changed it to

await splashAnim;

and it worked fine. This is a mistake because Promise.all should work with only with multiple promises and not one.

Upvotes: 0

Related Questions