VSF User Module Extension in 1.12.2

Hi All… Just question about the core user module.

What is the best way of extending a core module? Such as extending the user core module to accept date of birth field?

I have tried following these two resources.

But im not having much luck.

Im getting the following error

Type 'StorefrontModule' is missing the following properties from type 'VueStorefrontModule': _isRegistered, _c, _extendModule, config, registerts(2739)

Any help would be much appreciated.

created file src/modules/user/index.ts

import { UserModule } from '@vue-storefront/core/modules/user'
import { extendModule, VueStorefrontModule } from '@vue-storefront/core/lib/module'
import { Logger } from '@vue-storefront/core/lib/logger'

export const KEY = 'user'

const userStateExtend = {
  actions: {
    load () {
      Logger.info('Extended Action')()
    }
  }
}

const userAfterRegistration = function (VSF) {
  Logger.info('___________________EXTENDEDDDD________________________')()
}

const userExtension = {
  key: KEY,
  afterRegistration: userAfterRegistration,
  store: {
    modules: [{
      key: KEY,
      module: userStateExtend
    }]
  }
}

extendModule(userExtension)

export const registerModules: VueStorefrontModule[] = [UserModule]

You should use extendStore in this case. Check: https://docs.vuestorefront.io/guide/cookbook/module.html#_2-2-recipe-b-override-vuex-store-with-extendstore

I analyzed your problem with adding Date of Birth field to user’s profile. To implement this feature, you have to:

  1. Extend user’s module, especially USER_INFO_LOADED mutation - to add there dob property if it does not exist, so later it will be reactive. Example of module which does that:
// src/modules/vsf-dob/index.ts
import { USER_INFO_LOADED } from '@vue-storefront/core/modules/user/store/mutation-types';
import { StorefrontModule } from './../../../core/lib/modules';
import { extendStore } from '@vue-storefront/core/helpers';
const mutations = {
  [USER_INFO_LOADED] (state, currentUser) {
    state.current = {
      ...currentUser,
      ...(!currentUser.dob ? { dob: '' } : {})
    }
  }
}
const userModule = {
  mutations
}
export const ExtendedUser: StorefrontModule = function () {
  extendStore('user', userModule);
}

Of course, then you have to add it to src/modules/client.ts.

  1. In MyProfile.vue component you have mixin MyProfile which is compatibility layer and uses UserAccount mixin from core’s user module. Open: core/modules/user/components/UserAccount.ts and copy updateProfile method to your MyProfile.vue component - that way you will be able to overwrite it.
  2. Inside copied method you have to add dob to payload. As far as I remember it was just about adding:
updatedProfile.dob = this.currentUser.dob

Under:

updatedProfile.email = this.currentUser.email
  1. Add some UI field with v-model currentUser.dob and check whether it is being sent in payload to the POST /me (just try to save it with some value). Probably, it is but you receiving an error
  2. To prevent an error, you have to modify userProfileUpdate.schema.json (or even better userProfileUpdate.schema.extension.json in your vsf-api. It would be the best to add new field dob next to:
"lastname": {
    "type": "string",
    "pattern": "[a-zA-Z]+"
},

It might look like (I hope this pattern will be ok for you: :

"dob": {
    "type": "string",
    "pattern": "^[0-9]{4}-(1[0-2]|0[1-9])-(3[01]|[12][0-9]|0[1-9])$"
},

Test it now and tell me if you have any errors. If so put them in the answer.

thanks @Fifciuu.

Your above suggestion did the trick. however there was a couple of other api schema changes needed to get this working.

src/models/userProfileUpdate.schema.json:6 "additionalProperties": true,
src/models/userProfile.schema.json:6 "additionalProperties": true,

I also added a required input field for dob in MyProfile.vue with corresponding validation.

So far this allows us to add a date of birth field and edit the value in MyProfile.vue.

However there seems to be a bug when logging out of user.

index.ts:10 Uncaught (in promise) TypeError: Cannot read property 'dob' of null
at Store.push../src/modules/vsf-dob/index.ts._a.<computed> (index.ts:10)
at wrappedMutationHandler (vuex.esm.js:740)
at commitIterator (vuex.esm.js:392)
at Array.forEach (<anonymous>)
at vuex.esm.js:391
at Store._withCommit (vuex.esm.js:522)
at Store.commit (vuex.esm.js:390)
at Store.boundCommit [as commit] (vuex.esm.js:335)
at local.commit (vuex.esm.js:692)
at Store.clearCurrentUser (actions.ts:221)

commiting the USER_INFO_LOADED mutation on line core/modules/user/store/actions.ts:221
sets currentUser Object to null. which seems to break this.

I will also be looking into how to add this dob field as part of the user registration process.

Try switching:

...(!currentUser.dob ? { dob: '' } : {})

To the:

...(currentUser && !currentUser.dob ? { dob: '' } : {})