0

I'm using Pinia with Vue. My store looks like this:

interface LoginStore {
  token?: string;
}

export const useLoginStore = defineStore('login', {
  state: () => ({} as LoginStore),
  actions: {
    async login(email: string, password: string): Promise<boolean> {
      try {
        const result = await api.post('/api/user/login', { email, password });
        this.token = result.data.data.token;
        return true;
      } catch (err) {
        console.error('Login Error', err);
        return false;
      }
    },
  },
  getters: {
    isLoggedIn: (state) => {
      return state.token != null;
    }
  }
});

When I call loginStore.login() I can see the request succeeds, but the isLoggedIn getter continues to return false.

I'm using storeToRefs for the access, so it's not that I haven't remembered to restructure the store (this issue).

const { isLoggedIn } = storeToRefs(useLoginStore());

Why would isLoggedIn continue to be false after state.token is set?

stevex
  • 5,589
  • 37
  • 52

1 Answers1

1

Properties with type undefined need to be specified in the initial state of the store. Seems counterintuitive, but if you initialize it by leaving those out:

state: () => ({} as LoginStore),

Then the getter won't work. If you initialize them with undefined, the getter will work.

state: () => ({
  token: undefined,
} as LoginStore),
stevex
  • 5,589
  • 37
  • 52
  • 1
    It's a good practice to use null for such cases, this allows to clearly distinguish undefined and uninitialized values – Estus Flask Sep 25 '22 at 12:39