apollo
apollo copied to clipboard
Cannot use apollo in Typescript @Component decorator with 'components' key
In my vue typescript application, I'm trying to use vue apollo with the vue-property-decorator
library.
I have the following code:
import { Component, Prop, Vue } from 'vue-property-decorator'
import HeaderPrimary from '@/components/Header/HeaderPrimary.vue'
import query from '@/graphql/users.gql'
@Component({
components: { // Error from here
HeaderPrimary, // ...
}, // to here.
apollo: {
users: query,
},
})
export default class TheHeader extends Vue {
users: any = null
}
I'm receiving the following error:
Argument of type '{ components: { HeaderPrimary: {}; }; apollo: { users: DocumentNode; }; }' is not assignable to parameter of type 'VueClass<Vue>'.
Object literal may only specify known properties, but 'components' does not exist in type 'VueClass<Vue>'. Did you mean to write 'component'?
When I remove the apollo
part of the @Component
, the error goes away.
The app still runs fine and queries correctly, but unfortunately I'm not sure how to get past this TypeScript error.
I had the same type error problem and looked at the typings for the VueApolloComponentOptions
. It seems the query should be either a DocumentNode
or a function returning a DocumentNode
, but for some reason, it errors on the DocumentNode
alone.
Your error should be sorted out with
@Component({
components: {
HeaderPrimary,
},
apollo: {
users: () => query,
},
})
I have exactly the same issue and unfortunately @Kresten suggestion didn't work for me. Any help would be much appreciated :)
Source:
index.vue
import { Vue, Component } from 'vue-property-decorator';
import gqlTranslations from './translations.gql';
import Logo from '~/components/Logo.vue';
@Component({
components: {
Logo,
},
apollo: {
translations: {
query: gqlTranslations,
variables() {
return {
namespace: 'index',
language: 'en',
};
},
},
},
})
export default class IndexPage extends Vue {
private translations = {};
}
translations.gql
query translations($namespace: String!, $language: String!) {
translations(input: { namespace: $namespace, language: $language })
}
any solution to this?
@Acidic9 @jurgisrudaks @gdpaulmil
I suggest this is not gonna be happened if vue-apollo module is imported correct. If it's not loaded, it could be like as @Acidic9 said. like below
but if you import vue-apollo module somewhere on your codebase, it should be work.
As you can see error has disapieared.
That doesn't work for me. I've imported vue-apollo as shown and in multiple other places. The only situation that works for a DocumentNode
is assigning with a function:
import { SomeDocument } from 'documents'
apollo: {
thing: () => SomeDocument
}
@bbugh Can you share us whole of your example? This code is working for me..
<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import gqlTranslations from "./test.graphql";
import Logo from "~/components/Logo.vue";
import "vue-apollo";
@Component({
components: {
Logo
},
apollo: {
translations: () => gqlTranslations
}
})
export default class IndexPage extends Vue {
private translations = {};
}
</script>
Also I think you can write it like this. Does this work for you?
@Component({
components: {
Logo
},
apollo: {
translations: {
query: () => gqlTranslations
},
},
})
Using a function works but it's not ideal. When will this be fixed ?
It will be fixed by using the composition function. I'm almost giving up fixing all of those typing issues, which is both frustrating and taking way too much of my time (still open to PRs :smile_cat: ).
@Akryum
By mentioned about composition function, Do you mean Vue Composition API?
Could you help to explain how to use the composition function to fix this?
Is it like
setup() {
const apollo = {};
apollo.addSmartQuery('todoList', ...);
// expose to template
return {
apollo
}
}
or like this?
setup() {
const apollo = {
todoList: {
query: getTodoList
}
};
// expose to template
return {
apollo
}
}
See https://v4.apollo.vuejs.org/guide-composable/
Just add "vue-apollo"
in tsconfig.json
:
{
"compilerOptions": {
"types": [..., "vue-apollo"]
}
}
@Akryum the purpose of the composition API for vue 2 is to let developers experiment the composition API in Vue 3. But it is not something to be used in production, as stated on the repo in bold:
We do not recommend using this package for production yet at this stage
So using the composition API in Vue 2 seems not to be a viable solution, is it ? I think there should be both:
- a vue-apollo release for Vue 2 without using the composition API
- optionally a vue-apollo release for Vue 3 using exclusively the composition API
Don't you think solutions built around the composition API for Vue 2 will be compromised at Vue 3 release ?
I should add the purpose of this issue is to solve a typescript error, but using the composition API at the moment imply dozens of new typescript errors, unsolvable for most of them since they are in the @vue/composition-api
module
thanks , i got it that how to use vue-apollo in typescript!
Just add
"vue-apollo"
intsconfig.json
:{ "compilerOptions": { "types": [..., "vue-apollo"] } }
Worked for me. Thanks
I always geht a typeerror as soon as I try to add variables in the query. Any solution? :)
Maybe this will help someone. Vue2 + "vue-property-decorator" + vue-apollo It works for me:
<script lang="ts">
import { Component, Watch, Vue } from "vue-property-decorator";
import gql from "graphql-tag";
import { GET_COURSE } from "../../graphql/courses";`
@Component({
components: {
// other components
},
apollo: {
teacherCourse: {
query: GET_COURSE,
result(resp) {
// some logic
},
variables() {
return {
id: this.$route.params.slug,
};
},
},
},
})
export default class LessonsList extends Vue {
teacherCourse: object = {};
// some code
}
courses.ts
import gql from 'graphql-tag';
import 'vue-apollo';
export const GET_COURSE = gql`
query($id: UUID!) {
teacherCourse(input: { id: $id }) {
name
id
chapters {
id
name
courseID
lessons {
id
name
content
}
}
}
}
`;
And main.ts (just in case) if you want to see, how it is set up:
import Vue from 'vue';
import VueApollo from 'vue-apollo'
import App from './App.vue';
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
// HTTP connection to the API
const httpLink = createHttpLink({
// You should use an absolute URL here
uri: '/graphql',
credentials: 'include'
})
// Cache implementation
const cache = new InMemoryCache()
// Create the apollo client
const apolloClient = new ApolloClient({
link: httpLink,
cache,
})
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})
Vue.use(VueApollo);
new Vue({
// other stuff
apolloProvider,
el: '#app',
render: (h) => h(App),
});