Search code examples
vue.jsfrontendvue-componentrendering

Why does the text before the loading state appear for 1/2 sec after the loading state ends and the text changes? ( Render problem )


I have this Button component which displays a spinner when loading = true, to handle loading states, the switch right here is from track to tracking, those are the 2 texts that show up before and after loading. I'm using the devTools to see the state changing, but the problem is that right after loading=false the spinner stops and just for a second after switching to "tracking" it shows s the word "track" again. Here's the code:

// Following
    const isTracked = computed((): boolean =>
      store.state.user.following.includes(userID.value)
    )
    const isLoadingTracking = ref(false)
    const handleTracking = async (): Promise<void> => {
      try {
        isLoadingTracking.value = true
        if (isTracked.value) await unfollow(userID.value)
        else await follow(userID.value)
        store.dispatch('getProfileData')
      } catch (err) {
        store.commit('notify', { key: 'error', status: 'ERROR' })
      } finally {
        isLoadingTracking.value = false
      }
    }

          

Solution

  • store.dispatch('getProfileData') is asynchronous code.

    This means that, technically, the finally {} block executes before the code in your getProfileData action finishes.

    To fix it, place an await in front of store.dispatch('getProfileData'):

          try {
            isLoadingTracking.value = true
            if (isTracked.value) await unfollow(userID.value)
            else await follow(userID.value)
            await store.dispatch('getProfileData')
          } catch (err) {
            store.commit('notify', { key: 'error', status: 'ERROR' })
          } finally {
            isLoadingTracking.value = false
          }
    

    Alternate syntax for the above block:

          try {
            isLoadingTracking.value = true
            await (isTracked.value ? unfollow : follow)(userID.value)
            await store.dispatch('getProfileData')
          } catch (err) {
            store.commit('notify', { key: 'error', status: 'ERROR' })
          } finally {
            isLoadingTracking.value = false
          }