In my vue screen I'd like to use one apollo graphql I've defined for two properties. As far as I understand the name of the property must match a name of the attribute in the returned json structure.
I naivly tried to use the queries for two properties but it throws an error for the second one.
...
data() {
return {
userId: number,
user: null as User | null,
previousUserId: number,
previousUser: null as User | null
};
},
...
apollo {
user: {
query: READ_ONE_USER,
variables() {
return {
userId: this.userId
};
}
},
previousUser: {
query: READ_ONE_USER,
variables() {
return {
userId: this.previousUserId
};
},
export const READ_ONE_USER = gql(`
query user($userId: Int!) { user(userId: $userId)
{
id
firstName
lastName
email
}
}
`);
I expected no problems but I get "Missing previousUser attribute on result {user: ...}"
Daniel's solution didn't work out for me, I still got the same error message.
But there's another way to do it, you can provide an update function to tell apollo how to extract the result out of the data read from the server:
apollo {
user: {
query: READ_ONE_USER,
variables() {
return {
userId: this.userId
};
}
},
previousUser: {
query: READ_ONE_USER,
variables() {
return {
userId: this.previousUserId
};
},
update(data) {
return data.user;
}
}
This is documented at https://github.com/vuejs/vue-apollo/blob/v4/packages/docs/src/api/smart-query.md#options
As shown in the docs, you can manually add smart queries inside the created hook:
created () {
this.$apollo.addSmartQuery('user', {
query: READ_ONE_USER,
variables() {
return {
userId: this.userId
};
},
})
this.$apollo.addSmartQuery('previousUser', {
query: READ_ONE_USER,
variables() {
return {
userId: this.previousUserId
};
},
})
}
Related
I've been using vue.js for a few weeks and I would like to understand how to globally inject to child components an object coming from the server.
When I try to inject the object using inject:['user'] to a child component it returns an empty object.
data() {
return {
user: []
}
},
methods: {
getLoggedUserData() {
axios.get('/api/get-user/' + window.auth.id
).then(response => {
this.user = response.data.user;
});
}
},
provide: {
return {
user: this.user
}
},
created() {
this.getLoggedUserData();
}
The provide option should be a function in this case to get access to this.user property:
export default {
provide() {
return {
user: this.user
}
}
}
For descendants to observe any changes to the provided user, the parent must only update user by subproperty assignment (e.g., this.user.foo = true) or by Object.assign() (e.g., Object.assign(this.user, newUserObject)):
export default {
methods: {
async getLoggedUserData() {
const { data: user } = await axios.get('https://jsonplaceholder.typicode.com/users/1')
// ❌ Don't do direct assignment, which would overwrite the provided `user` reference that descendants currently have a hold of:
//this.user = user
Object.assign(this.user, user) ✅
}
}
}
demo
I'm using expressjs and apollo-server-express. I'm trying to set up a query in graphql to return a product from my database. The problem is that the results never show up in graphql, but when I console log resultsArr the results show up fine. Just to note the resultsArr is an array of objects.
Express:
const typeDefs = gql`
type Search {
brand: String
title: String
url: String
thumbnail: String
}
type Query {
results(query: String!): Search
}
`;
const resolvers = {
Query: {
results: (parent, args) => {
const queries = [
{
indexName: 'products',
query: args.query,
params: {
hitsPerPage: 1,
},
},
//
];
return AlgoliaClient.multipleQueries(queries).then(({ results }) => {
// Store Results
const resultsArr = [];
results.forEach((item) => {
resultsArr.push(item.hits[0]);
});
// console logging this shows the products
return resultsArr;
});
},
},
};
and my query the graphql playground is:
query Search {
results(query: "Test product") {
title
}
}
The problem is when I console log resultsArr the products show up no problem, however when it try it though the query I get:
{
"data": {
"results": {
"title": null
}
}
}
For some reason this was giving me trouble this morning, and I just couldn't figure out why it wouldn't work.
I have a variable 'applications' set equal to the data returned by my axios call. I want to include 'applications.name' as a field in my data() to send as a form. However when I try this, Vue gives me an error saying 'Cannot read property 'name' of undefined'.
{{applicants.name}} and {{applicants.role}} are working in the template, so I'm not just getting empty data
Also another thing, data() doesn't seem to recognize my 'this.loggedInUser.id' field either for some reason. (I've imported both Vuex and mapGetters)
Appreciate the help! :)
async asyncData({ $axios, params }) {
try {
let applicants = await $axios.$get(`/api/v1/apps/${params.id}/`);
return { applicants };
} catch (error) {
console.log(error);
return { applicants: [] };
}
},
data() {
return {
applicants: [],
application: {
name: this.applicants.name,
status: null,
company: null,
role: this.applicants.role
// user: this.loggedInUser.id
}
};
}
};
Try to pass this as parameter to the data property function:
data(vm) { //refers to this keyword
return {
applicants: [],
application: {
name: vm.applicants.name,
status: null,
company: null,
role: vm.applicants.role
// user:vm.loggedInUser.id
}
};
}
or make application as a computed property :
data() {
return {
applicants: [],
};
}
,
computed:{
application(){
return {
name: this.applicants.name,
status: null,
company: null,
role: this.applicants.role
// user: this.loggedInUser.id
}
}
}
I am assuming that when the data is initialized, the values applicants.name and loggedInUser.id do not exist. Try changing the data like this
data() {
return {
applicants: { name: '' },
application: {
name: this.applicants.name,
},
loggedInUser: { id: '' }
};
}
In Nuxt.js, I'm trying to do a query like this with the nuxt apollo-module based in vue-apollo
apollo: {
magazines: {
query: gql`query($id: String!) {
magazines( where: { url_contains:$id })
{
url
title
thumbnail
}
}`,
prefetch: ({ route }) => ({ id: route.params.id }),
variables() {
return {
id: this.$route.params.id
}
}
}
The query is sent, but the variable $id is sent unrendered (in the petition, I can see query($id: String!)—instead of query('my-page-route': String!)— and where: { url_contains:$id } as it is—instead of where: { url_contains:'my-page-route' }
The query is surprisingly valid, as it responds with all the items in the db —so it doesn't apply the where: { url_contains:$id }
I have tried with query($id: String) but that doesn't change anything. Any hints about what could be going wrong?
Thanks in advance!
I would like to create a checkout object via the GraphQL API provided by the Saleor eCommerce platform.
According to the gql playground there is a mutation to do so that takes a CheckoutCreateInput object as it's argument.
Here is an example mutation that works fine within the playground.
Here is the current code that I have tried (I am doing this within a vuex action)
export const actions = {
addToCart({ commit, dispatch }, cartItem) {
const currentCartItems = this.state.cartItems
// Check to see if we already have a checkout object
if (this.state.checkoutId !== '') {
// Create a new checkout ID
console.log('creating new checkout object')
try {
this.app.apolloProvider.defaultClient
.mutate({
mutation: CREATE_CART_MUTATION,
variables: {
checkoutInput: {
lines: { quantity: 10, variantId: 'UHJvZHVjdFZhcmlhbnQ6NQ==' },
email: 'test#test.com'
}
}
})
.then(({ data }) => {
console.log(data)
})
} catch (e) {
console.log(e)
}
} else {
console.log('checkout id already set')
}
// TODO: Check to see if the cart already contains the current Cart Item
commit('ADD_CART_ITEM', cartItem)
}
and here is the CREATE_CART_MUTATION:
import gql from 'graphql-tag'
export const CREATE_CART_MUTATION = gql`
mutation($checkoutInput: CheckoutCreateInput!) {
checkoutCreate(input: $checkoutInput) {
checkout {
id
created
lastChange
lines {
id
variant {
id
name
}
quantity
totalPrice {
gross {
localized
}
net {
localized
}
}
}
totalPrice {
gross {
localized
}
net {
localized
}
}
}
}
}
`
On the server this comes back with the following error:
graphql.error.base.GraphQLError: Variable "$checkoutInput" got invalid value {"email": "test#test.com", "lines": {"quantity": 10, "variantId": "UHJvZHVjdFZhcmlhbnQ6NQ=="}}.
In field "lines": In element #0: Expected "CheckoutLineInput", found not an object.
Looks like I was most of the way there, I was just passing a single lines object rather than an array of them. The correct code is as follows:
try {
this.app.apolloProvider.defaultClient
.mutate({
mutation: CREATE_CART_MUTATION,
variables: {
checkoutInput: {
lines: [
{ quantity: cartItem.quantity, variantId: cartItem.variantId }
],
email: 'test#test.com'
}
}
})
.then(({ data }) => {
console.log('mutation done!')
commit('SET_CHECKOUT_OBJECT', data.checkoutCreate.checkout)
})
} catch (e) {
console.log('error:')
console.log(e)
}