diff --git a/src/components/ApolloMutation.js b/src/components/ApolloMutation.js new file mode 100644 index 0000000..88e374c --- /dev/null +++ b/src/components/ApolloMutation.js @@ -0,0 +1,76 @@ +export default { + props: { + mutation: { + type: Object, + required: true, + }, + + variables: { + type: Object, + default: undefined, + }, + + optimisticResponse: { + type: Object, + default: undefined, + }, + + update: { + type: Function, + default: undefined, + }, + + refetchQueries: { + type: Function, + default: undefined, + }, + + tag: { + type: String, + default: 'div', + }, + }, + + data () { + return { + loading: false, + error: null, + } + }, + + methods: { + async mutate (options) { + this.loading = true + this.error = null + try { + await this.$apollo.mutate({ + mutation: this.mutation, + variables: this.variables, + optimisticResponse: this.optimisticResponse, + update: this.update, + refetchQueries: this.refetchQueries, + ...options, + }) + this.$emit('done') + } catch (e) { + this.error = e + this.$emit('error', e) + } + this.loading = false + }, + }, + + render (h) { + let result = this.$scopedSlots.default({ + mutate: this.mutate, + loading: this.loading, + error: this.error, + }) + if (Array.isArray(result)) { + result = result.concat(this.$slots.default) + } else { + result = [result].concat(this.$slots.default) + } + return h(this.tag, result) + }, +} diff --git a/src/index.js b/src/index.js index 9d168c7..be20b65 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,7 @@ import { DollarApollo } from './dollar-apollo' import { ApolloProvider as apolloProvider } from './apollo-provider' import CApolloQuery from './components/ApolloQuery' import CApolloSubscribeToMore from './components/ApolloSubscribeToMore' +import CApolloMutation from './components/ApolloMutation' import { Globals } from './utils' const keywords = [ @@ -39,6 +40,11 @@ const launch = function launch () { // watchQuery for (let key in apollo) { if (key.charAt(0) !== '$') { + Object.defineProperty(this, key, { + get: () => this.$apolloData.data[key], + enumerable: true, + configurable: true, + }) this.$apollo.addSmartQuery(key, apollo[key]) } } @@ -124,6 +130,7 @@ export function install (Vue, options) { '$apolloData': { queries: {}, loading: 0, + data: {}, }, } : {} }, @@ -145,6 +152,8 @@ export function install (Vue, options) { Vue.component('ApolloQuery', CApolloQuery) Vue.component('apollo-subscribe-to-more', CApolloSubscribeToMore) Vue.component('ApolloSubscribeToMore', CApolloSubscribeToMore) + Vue.component('apollo-mutation', CApolloMutation) + Vue.component('ApolloMutation', CApolloMutation) } } @@ -160,6 +169,7 @@ export { willPrefetch } from './apollo-provider' // Components export const ApolloQuery = CApolloQuery export const ApolloSubscribeToMore = CApolloSubscribeToMore +export const ApolloMutation = CApolloMutation // Auto-install let GlobalVue = null diff --git a/src/smart-query.js b/src/smart-query.js index b96ef5d..32ac0a3 100644 --- a/src/smart-query.js +++ b/src/smart-query.js @@ -103,12 +103,14 @@ export default class SmartQuery extends SmartApollo { if (typeof data === 'undefined') { // No result - } else if (typeof this.options.update === 'function') { - this.vm[this.key] = this.options.update.call(this.vm, data) - } else if (data[this.key] === undefined && !this.options.manual) { - console.error(`Missing ${this.key} attribute on result`, data) } else if (!this.options.manual) { - this.vm[this.key] = data[this.key] + if (typeof this.options.update === 'function') { + this.vm.$set(this.vm.$apolloData.data, this.key, this.options.update.call(this.vm, data)) + } else if (data[this.key] === undefined) { + console.error(`Missing ${this.key} attribute on result`, data) + } else { + this.vm.$set(this.vm.$apolloData.data, this.key, data[this.key]) + } } else if (!hasResultCallback) { console.error(`${this.key} query must have a 'result' hook in manual mode`) }