I am using Nuxt in SPA mode and have a page structure like this:
pages
...
- users/
- - index
- - new
- - update/
- - - _id
...
I have a page of users with a list of them and 'subpage' - new.
On my users/index page I am fetching my users in asyncData Hook like this:
async asyncData({ app: { apolloProvider }, store: { commit, dispatch } }) {
const {
data: { getAllUsers: { success, users, message } },
} = await apolloProvider.defaultClient.query({
query: getAllUsersGQL,
})
if(success) {
await commit('user/setUsers', users, { root: true })
} else {
dispatch('snackbar/notify', { message: message, type: 'error' }, { root: true })
}
},
It seems to work as it should. But when I go to my page users/new, fill up the form and send it, update the store and redirect to my users/index page, I encounter kinda interesting behaviour.
The problem here is that I don't have a newly updated state but some kinda cached one or previous state. I can so far make it working with location.replace. When the page reloads I have an accurate and updated state.
That's how I'm handling redirect on users/new page:
async save() {
if(this.$refs.create.validate()) {
this.loading = true
delete this.form.confirm
await this.createUserStore(this.form)
this.$router.push(
this.localeLocation({
name: 'users',
})
)
this.loading = false
this.$refs.create.reset()
}
},
and that's how I am refreshing my state in Vuex:
export const mutations = {
updateUsers: (state, payload) => {
state.users = [...state.users, payload].sort((a,b) => a.createdAt - b.createdAt)
},
}
That's how I'm passing data:
computed: {
...mapGetters({
storeUsers: 'user/getUsers',
storeGetMe: 'auth/getMe',
}),
},
<v-data-table
:headers="headers"
:items="storeUsers"
:search="search"
item-key="id"
class="elevation-1"
dense
>
</v-data-table>
I already tried to list items using v-for and it doesn't work either. And when I console.log state I get all items. It works as it should.
What can be the problem that it's not updating the view?
If anyone has ever faced such kind of behaviour I'd appreciate any hints.
This is probably coming from the fact that Apollo does have it's own cache and that it reaches for the cache first as cache-first is the default value.
Give this one a try
await apolloProvider.defaultClient.query({
query: getAllUsersGQL,
fetchPolicy: 'network-only',
})
This is an example of a dynamic GQL query that I previously wrote
test.gql.js
import { gql } from 'graphql-tag'
import { constantCase, pascalCase } from 'change-case'
export const queryCompanyBenefitInfo = ({
benefitType,
needCifEligibility = false,
needActiveOnWeekend = false,
needCompanyContribution = false,
needAutoRenewed = false,
needUnitValue = false,
}) => {
return gql`
query {
CompanyBenefit {
oneOfType(benefitType: ${constantCase(benefitType)}) {
... on Company${pascalCase(benefitType)}Benefit {
${needCifEligibility ? 'cifEligibility' : ''}
${needActiveOnWeekend ? 'activeOnWeekend' : ''}
${needCompanyContribution ? 'companyContribution' : ''}
${needAutoRenewed ? 'autoRenewed' : ''}
${
needUnitValue
? `unitValue {
value
}`
: ''
}
}
}
}
}
`
}
And call it this way
import { testQuery } from '~/apollo/queries/test.gql.js'
...
await this.app.apolloProvider.defaultClient.query({
query: testQuery({ benefitType: 'care', needCifEligibility: true }),
fetchPolicy: 'network-only',
errorPolicy: 'all',
})