Vuex 4 in vue composition api

187 Views Asked by At

I am running to a problem where my user object is not being populated in time for the rest of my component to use it. In vuex, I am dispatching an action where I call the fetchAuthUser. The following is the store for User

import axios from "axios";

const state = () => ({
    user: null,
    userStatus: null
})

const getters = {
    authUser: state => {
        return state.user
    }
}

const actions = {
    async fetchAuthUser({commit}) {
        await axios.get('/auth-user')
            .then(res => {
                commit('setAuthUser', res.data);
            })
            .catch(error => {
                console.log('Unable to fetch auth user');
            });
    }
}

const mutations = {
    setAuthUser(state, user) {
        state.user = user
    }
}

export default {
    namespaced: true,
    state,
    getters,
    actions,
    mutations,

}

No in my component I am calling the following

store.dispatch('User/fetchAuthUser');
const user = computed(() => {
  return store.getters['User/authUser'];
});

Whenever I try to access the user object to get a list of posts that are assigned to the user, the user object is always null, meaning it's not populated prior to using it.

store.dispatch("Posts/fetchUserPosts", user.data.user_id);

I have the async and the await on the fetchAuthUser function, so why does the code to fetch the posts still executes

So how can I get the use robjet populated before it gets accessed.

the following is my component code:

<script setup lang="ts">

import {computed, defineComponent, onBeforeMount} from "vue";
import {useStore} from "vuex";
import {Head} from "@inertiajs/vue3";
import AuthenticatedLayout from "@/Layouts/Community/AuthenticatedLayout.vue";
import Post from "@/Pages/Community/Post.vue";

defineComponent({Post})

const store = useStore();

store.dispatch('User/fetchAuthUser');
const user = computed(() => {
  return store.getters['User/authUser'];
});


  store.dispatch("Posts/fetchUserPosts", user.data.user_id);

  const posts = computed(() => store.getters["Posts/posts"]);
  const newsStatus = computed(() => store.getters["Posts/newsStatus"]);

  const friendButtonText = computed(() => {
    return store.getters["Profile/friendButtonText"]
  })

  const friendship = computed(() => {
    return store.getters["Profile/friendship"]
  })

  const sendFriendRequest = (friendId: number) => {
    store.dispatch('Profile/SendFriendRequest', friendId)
  }

  const acceptFriendRequest = (userId: number) => {
    store.dispatch('Profile/AcceptFriendRequest', userId);
  }

  const ignoreFriendRequest = (userId: number) => {
    store.dispatch('Profile/IgnoreFriendRequest', userId);
  }

  const unfriend = (friendId: number) => {
    store.dispatch('Profile/Unfriend', friendId);

  }




</script>

<template>
  <Head title="Profile"/>
  <AuthenticatedLayout>
    <div class="flex flex-col items-center" v-if="user">
      <div class="relative mb-8">
        <div class="w-100 h-64 z-10 overflow-hidden">
          <img
              src="https://images.pexels.com/photos/2662116/pexels-photo-2662116.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
              alt="" class="object-cover w-full">
        </div>
        <div class="absolute flex items-center bottom-0 left-0 ml-12 -mb-8 z-20">
          <div class="w-32">
            <img
                src="https://img.freepik.com/free-photo/portrait-white-man-isolated_53876-40306.jpg?w=996&t=st=1687871471~exp=1687872071~hmac=4e38748c6d278550acda8ec15451c5f1798d86a82fc03d13e41835cfa3f25cf3"
                alt="" class="object-cover w-32 h-32 border-4 border-gray-200 rounded-full shadow-lg">
          </div>
          <p class="ml-4 text-2xl text-gray-100">{{ user.data.attributes.name }}</p>
        </div>
                        <div class="absolute flex items-center bottom-0 right-0 mr-12 mb-4 z-20" v-if="friendButtonText && friendButtonText === 'Add Friend'">
                            <button class="py-1 px-3 bg-gray-400 rounded" @click.prevent="sendFriendRequest(user.data.user_id)">{{ friendButtonText }}</button>
                        </div>

                        <div class="absolute flex items-center bottom-0 right-0 mr-12 mb-4 z-20" v-if="friendButtonText && friendButtonText === 'Pending Friend Request'">
                            <button class="py-1 px-3 bg-gray-400 rounded" @click.prevent="unfriend(friendship.data.attributes.friend_id)">{{ friendButtonText }}</button>
                        </div>

                        <div class="absolute flex items-center bottom-0 right-0 mr-12 mb-4 z-20" v-if="friendButtonText && friendButtonText === 'Unfriend'">
                            <button class="py-1 px-3 bg-gray-400 rounded" @click.prevent="unfriend(friendship.data.attributes.friend_id)">{{ friendButtonText }}</button>
                        </div>

                        <div class="absolute flex items-center bottom-0 right-0 mr-12 mb-4 z-20" v-if="friendButtonText && friendButtonText === 'Accept'">
                            <button class="mr-2 py-1 px-3 bg-blue-500 rounded" @click.prevent="acceptFriendRequest(user.data.user_id)">Accept</button>
                            <button class="py-1 px-3 bg-gray-400 rounded" @click.prevent="ignoreFriendRequest(user.data.user_id)">Ignore</button>
                        </div>

      </div>

                  <p v-if="newsStatus.postsStatus === 'loading'">Loading posts...</p>
                  <Post v-else v-for="(post, postKey) in posts.data" :key="postKey" :post="post"/>

    </div>


  </AuthenticatedLayout>
</template>

<style scoped>

</style>
0

There are 0 best solutions below