Why does Apollo/GraphQL return a non extensible object?

Viewed 1895

I'm building an app with VueJS and I'm using Apollo client to fetch data from a database through a GrapgQL server. I have code that looks like this:

    apollo.query({
        query,
        variables
    })
    // context.commit('populateComments', payload) triggers the mutation
    .then(payload => context.commit('populateComments', payload))

Then, in my mutations I have the following

    populateComments: (state, payload) => { 
        state.comments = payload.data.comments
    }

When I try to push another object into the comments array in another mutation I get an error that reads "Cannot add property 300, object is not extensible". I have found that the following works

state.comments = Array.from(payload.data.comments)

But.. I'm not sure how effective it is to repeatedly copy large arrays like this? Is this the preferred way to do it?

4 Answers

Haven't worked with GraphQL/Apollo myself, but I guess it would hold to the principle of not mutating the data, hence the object not being extensible. What you can do in your mutations is to assign the data to the state like this:

Vue.set(state, 'comments', payload.data.comments)

This will make sure that the object is initially deep copied and afterwards updated in a Vue friendly way in order to support reactivity. You can read more here.

This should work:

const commentsClone = [...payload.data.comments];

I've faced the exact same problem.

What I ended up doing is doing a _.cloneDeep before I send the data in to Vue commit.

Related