Get number of items in content folder in a nuxt blog

395 Views Asked by At

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.

1

There are 1 best solutions below

0
On BEST ANSWER

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.