I recently completed a tutorial on Vue to enhance my skills, and I'm now facing an issue while trying to make some changes. The tutorial I followed can be found here.
Specifically, I have a "settings" page where users can edit their profile details. When the "settings" or "profile" page loads, I want the form to display their existing data so they can easily make modifications and save them.
Currently, the form loads with placeholders like
:placeholder="userProfile.name"
. Instead, I want the form to populate with the actual values rather than just placeholders.
Although it seems like a simple task, I've been struggling to implement this effectively.
Settings.vue
<template>
<section id="settings">
<div class="col1">
<h3>Settings</h3>
<p>Update your profile</p>
<transition name="fade">
<p v-if="showSuccess" class="success">profile updated</p>
</transition>
<form @submit.prevent>
<label for="name">Name</label>
<input v-model.trim="name" type="text" id="name" />
<label for="title">Job Title</label>
<input v-model.trim="title" type="text" id="title" />
<button @click="updateProfile()" class="button">Update Profile</button>
</form>
</div>
</section>
</template>
<script>
import { mapState } from "vuex";
export default {
data() {
return {
name: "",
title: "",
showSuccess: false,
};
},
computed: {
...mapState(["userProfile"]),
},
methods: {
updateProfile() {
this.$store.dispatch("updateProfile", {
name: this.name !== "" ? this.name : this.userProfile.name,
title: this.title !== "" ? this.title : this.userProfile.title,
});
this.name = "";
this.title = "";
this.showSuccess = true;
setTimeout(() => {
this.showSuccess = false;
}, 2000);
},
},
};
</script>
<style lang="scss" scoped>
</style>
After attempting to modify the data section as shown below, the fields work fine when navigating away and returning to the page. However, upon refreshing the page (F5), the fields appear blank until leaving and reentering the page again.
data() {
return {
name: this.$store.state.userProfile.name,
title: this.$store.state.userProfile.title,
showSuccess: false,
};
},
For reference, here is my store configuration:
store/index.js
import Vue from "vue";
import Vuex from "vuex";
import * as fb from "../firebase";
import router from "../router/index";
Vue.use(Vuex);
// Firebase Firestore real-time connection
fb.postsCollection.orderBy("createdOn", "desc").onSnapshot((snapshot) => {
let postsArray = [];
snapshot.forEach((doc) => {
let post = doc.data();
post.id = doc.id;
postsArray.push(post);
});
store.commit("setPosts", postsArray);
});
const store = new Vuex.Store({
state: {
userProfile: {},
posts: [],
},
mutations: {
setUserProfile(state, val) {
state.userProfile = val;
},
setPosts(state, val) {
state.posts = val;
},
},
actions: {
async signup({ dispatch }, form) {
// User sign up process
const { user } = await fb.auth.createUserWithEmailAndPassword(
form.email,
form.password
);
// Create user profile object in userCollections
await fb.usersCollection.doc(user.uid).set({
name: form.name,
title: form.title,
});
// Fetch user profile and set in state
dispatch("fetchUserProfile", user);
},
// Other action methods...
},
modules: {},
});
export default store;
EDIT
I should note that the profile data is being loaded into the state from Firebase Firestore. It appears to be a timing issue, where the data isn't completely loaded before setting the component's data(). I added some console logs to track the process:
Fetching user profile.. Settings.vue?e12e:29
Setting Data... index.js?4360:75
Performing setUserProfile commit.. index.js?4360:29
Setting user profile in state, last step..
At this stage, my understanding of Vue is limited, making it challenging to determine the best approach to adjust this sequence.