1

In my Nuxt page I have a navigation component where I try to achieve something like

[Logo] [Product] [Infos] [Jobs(2)]

Where (2) is a flag representing the number of items in the corresponding "jobs" content folder. I tried to fill the state but couldn't get it working. My state looks like this:

export const state = () => ({
  jobsLength: null,
})

export const mutations = {
  setJobsLength(state, payload) {
    state.jobsLength = payload.length
  },
}

export const getters = {
  getJobsLength(state) {
    return state.jobsLength
  },
}

export const actions = {
  async fetch({ $content, commit }) {
    const jobs = await $content('jobs').fetch()
    commit('setJobsLength', jobs.length)
  },
}

My Navigation.vue Component:

<a href="/jobs">
    Jobs {{ getJobsLength }}
</a>

....

<script>
import { mapGetters, mapMutations, mapActions } from 'vuex'

export default {
  computed: {
      ...mapGetters({
          getJobsLength: 'jobsLength/getJobsLength',
      }),
  },
  mounted() {
      this.fetchJobs()
  },
  methods: {
      ...mapActions({
          fetchJobs: 'jobsLength/fetch',
      }),
  },
}
</script>

The response is

Uncaught (in promise) TypeError: $content is not a function

I feel like I'm missing something but after like 2-3h in the code I'm blind.

kissu
  • 40,416
  • 14
  • 65
  • 133
  • What happens if you `const jobs = await $content('jobs').fetch()` and then, `job.length` inside of you `.vue` component ? Without vuex, directly in your component. – kissu Apr 30 '21 at 01:26
  • @kissu I have multiple places/components where I want to use the value (desktop navigation, mobile navigation, footer, etc...) But in other ways I use your solution right now as I've built a component just for the value. – Robin Schreiner Apr 30 '21 at 13:19

1 Answers1

1

Your error is probably coming from the fact that you're passing a number to your commit already (jobs.length)

commit('setJobsLength', jobs.length)

But in your mutation, you do use length again. A correct version would be this:

setJobsLength(state, arrayLength) { // better naming, rather than payload
  state.jobsLength = arrayLength
},

Also, make it easy for yourself, strip the getter and use the state directly

...mapState('jobsLength', ['jobsLength'])
// btw here the namespaced module should probably be renamed to something more generic like "jobs"
...mapState('jobs', ['jobsLength'])

Same goes for your action, why not call it directly async fetchJobs({ $content, commit }) rather than renaming it afterwards.

Finally, do not forget to make an async mounted since your action is async

async mounted() {
    await this.fetchJobs()
},

PS: Vuex can be overkill and complicate things. If you don't need jobsLength globally, use a local state.

kissu
  • 40,416
  • 14
  • 65
  • 133