I am building a nativescript mobile application which consume graphql API, and I am using apollo client via apollo boost.
The problem appear when I am trying to send array of objects inside the mutation like below:
let {
to,
total,
drugList
} = order
apolloClient.mutate({
mutation: gql `mutation {
makeOrder(
to: "${to}",
total: ${total},
drugList: ${drugList}
){
id
}
}`
}).then((res) => {
console.log(res)
}).catch((error) => {
console.log(error)
})
I have tried to log the drugList inside a template literals like:
console.log(`${drugList}`)
But I got [object object],[object object] then I have tried to use ${[...drugList]} instead and I got the desired structure of array of objects but the mutate function of apollo client doesn't accept it (doesn't execute the mutation or log an error).
Am I miss something to make it run or are there any recommendation to run it?
Thanks to Bergi, after his notice that gql-tagged template literal cannot be compared to the simple template string in a console.log test.
So I have searched around this and figured out that variables property would solve this problem.
Here is the final result:
let {
to,
total,
drugList
} = order
apolloClient.mutate({
mutation: gql `mutation ($to: ID!, $total: Float!, $drugList: [OrderDrugsListInput!]!) {
makeOrder(
to: $to,
total: $total,
drugList: $drugList
){
id
}
}`,
variables: {
to: to,
total: total,
drugList: drugList
}
}).then((res) => {
console.log(res)
}).catch((error) => {
console.log(error)
})
Related
I use firebase firestore db. This project have two main collection "securecollection" and "publiccollection". The securecollection is where all important data is stored and only accessible to authenticated users. But in order for some information to be visible to guest users, I am copying them into the publiccollection. Then, I want to save the id of this newly created public document in the secure document.
When I write a variable
db.collection('securecollection').doc(secureDocid).update({ inside the query sentence, I get this error:
Uncaught (in promise) TypeError: o.indexOf is not a function
If I write the id as text db.collection('securecollection').doc('7llDqIWlmE5VM69Zzle2').update({, the code works.
Here is my code:
function toggleOlustur(secureDocid) {
const db = firebase.firestore();
db.collection("securecollection").get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
if (doc.id == secureDocid) {
db.collection("publiccollection").add({
oad: doc.data().oad,
osad: doc.data().osad,
opuan: doc.data().opuan,
odtarih: doc.data().odtarih,
odurum: "1",
})
.then((docRef) => {
db.collection('securecollection').doc(secureDocid).update({
preference: docRef.id
})
});
}
});
});
}
The doc() method expects a string argument, and from the error message it sounds like your secureDocid is not a string value. If you console.log(JSON.stringify(secureDocid)) you can see what it outputs, which might help to figure out the problem.
I am using postsConnection query for infinite scroll. It contains variables like after.
After doing an upvote mutation, I want to refetchQueries... like this 👇
const upvote = await client.mutate({
mutation: UPVOTE_MUTATION,
variables: {
postId: this.props.post.id
},
refetchQueries: [
{ query: POST_AUTHOR_QUERY }
]
})
Above code gives error because POST_AUTHOR_QUERY accepts few variables. Here's that query 👇
export const POST_AUTHOR_QUERY = gql`
query POST_AUTHOR_QUERY($authorUsername: String! $orderBy: PostOrderByInput $after: String){
postsAuthorConnection(authorUsername: $authorUsername orderBy: $orderBy after: $after) {
....
}
}
I do not want to add variables manually. Variables are already stored in the cache. How do I reuse them while using refetchQueries???
Here are a few resources I have read about this issue 👇
https://github.com/apollographql/react-apollo/issues/817
https://github.com/apollographql/apollo-client/issues/1900
As mentioned in the issue you linked, you should be able to do the following:
import { getOperationName } from 'apollo-link'
const upvote = await client.mutate({
// other options
refetchQueries={[getOperationName(POST_AUTHOR_QUERY)]}
})
From the docs:
Please note that if you call refetchQueries with an array of strings, then Apollo Client will look for any previously called queries that have the same names as the provided strings. It will then refetch those queries with their current variables.
getOperationName simply parses the document you pass it and extracts the operation name from it. You can, of course, provide the operation name yourself as a string instead, but this way avoids issues if the operation name changes in the future or you fat finger it.
If you don't want to pull in apollo-link, you can also get this via the base graphql package (note that I use optional chaining for convenience:
import { getOperationAST } from 'graphql';
const operationName = getOperationAST(POST_AUTHOR_QUERY)?.name?.value;
// Note that this could technically return `undefined`
const upvote = await client.mutate({
mutation: UPVOTE_MUTATION,
variables: {
postId: this.props.post.id
},
refetchQueries: [operationName]
})
This is the method I'm using, pretty simple.
DailyCountTest: function (){
this.$store.dispatch("DailyCountAction")
let NewPatientTest = this.$store.getters.NewPatientCountGET
console.log(NewPatientTest)
}
The getter gets that data from a simple action that calls a django backend API.
I'm attempting to do some charting with the data so I need to assign them to variables. The only problem is I can't access the variables.
This is what the console looks like
And this is what it looks like expanded.
You can see the contents, but I also see empty brackets. Would anyone know how I could access those values? I've tried a bunch of map.(Object) examples and couldn't get any success with them.
Would anyone have any recommendation on how I can manipulate this array to get the contents?
Thanks!
Here is the Vuex path for the API data
Action:
DailyCountAction ({ commit }) {
axios({
method: "get",
url: "http://127.0.0.1:8000/MonthlyCountByDay/",
auth: {
username: "test",
password: "test"
}
}).then(response => {
commit('DailyCountMutation', response.data)
})
},
Mutation:
DailyCountMutation(state, DailyCount) {
const NewPatientMap = new Map(Object.entries(DailyCount));
NewPatientMap.forEach((value, key) => {
var NewPatientCycle = value['Current_Cycle_Date']
state.DailyCount.push(NewPatientCycle)
});
}
Getter:
NewPatientCountGET : state => {
return state.DailyCount
}
State:
DailyCount: []
This particular description of your problem caught my eye:
The getter gets that data from a simple action that calls a django backend API
That, to me, implies an asynchronous action and you might be getting a race condition. Would you be able to post a sample of your getter function to confirm my suspicion?
If that getter does indeed rely on an action to populate its contents, perhaps something to the effect of the following might do?
DailyCountTest: async () => {
await this.$store.dispatch('DailyCountAction')
await this.$store.dispatch('ActionThatPopulatesNewPatientCount')
let NewPatientTest = this.$store.getters.NewPatientCountGET
// ... do whatever with resulting array
}
You can also try with a computer property. You can import mapGetters
import { mapGetters } from 'vuex'
and later in computed properties:
computed: {
...mapGetters(['NewPatientCountGET'])
}
then you can use your NewPatientCountGET and it will update whenever the value changes in the store. (for example when the api returns a new value)
Hope that makes sense
I am subscribing to my data from an http get method:
getEds(): void {
this.edService.getEds()
.subscribe((eds: Education) => {
this.eds = eds.educationData;
console.log(this.eds:codeschool);
});
}
I am trying to display my courses for codeschool in an *ngFor loop but do not know how to access the data. My console log will show the entire array of objects so I know I am receiving the correct info. I've tried various syntax:
.subscribe((eds: any) => {
this.eds = eds.educationData.course;
.subscribe((eds: any) => {
this.eds = eds.educationData['codeschool'];
.subscribe((eds: any) => {
this.eds = eds.educationData.codeschool;
None of these syntax work and the log shows undefined. I found this page which has great info and what I tried to use as a baseline.
Access / process (nested) objects, arrays or JSON
However, I do not know what is wrong or why I cannot get the data I need. When I use
.subscribe((eds: any) => {
this.eds = eds.educationData;
and I log out (this.eds), my log shows:
[{…}]
0:{codeschool: Array(14), egghead: Array(6)}
length:1
__proto__:Array(0)
Beyond this I haven't been able to get the data I want...... :(
use this :
eds.educationData[0].codeschool
What is the 'meteor'-way to get a document title by a given ID?
Collection (Articles)
{
'_id' : 'Dn59y87PGhkJXpaiZ',
'title' : 'Sample Article',
'slug' : 'sample-article'
}
client
render() {
const data = [
{ _id: 'Dn59y87PGhkJXpaiZ' },
{ _id: 'kJXpaiZDn59y87PGh' }
{ _id: 'y87PGhkJXpaiZDn59' }
]
return (
<List>
{
data.map(r => {
return <List.Item>r._id</List.Item>
})
}
)
}
With this I will get this output:
<List>
<List.Item>Dn59y87PGhkJXpaiZ</List.Item>
<List.Item>kJXpaiZDn59y87PGh</List.Item>
<List.Item>y87PGhkJXpaiZDn59</List.Item>
</List>
Now I want to display the title instead of the id. So normally I would do
data.map(r => {
const title = Articles.findOne({ _id: r._id }).title
return <List.Item>title</List.Item>
})
But the problem is, that data is a dynamic dataset and I can't/don't want to publish the complete Articles collection. Right now there is no subscription, so I don't get any results for the title.
So I think I have to do a server side call.
Meteor.call('getTitle', r._id, function(err, res) {
console.log(res)
})
But then I'll get the result in the callback function. So how do I get these into the list? Also I want to avoid multiple method calls. I think it would be better to send data and get all titles on server side and then build the list.
If you can/want to use a non async call, don't pass a callback to the Meteor.call() method:
data.map(r => {
const title = Meteor.call('getTitle',r._id);
return <List.Item>title</List.Item>
})
As stated in the docs:
If you do not pass a callback on the server, the method invocation will block until the method is complete. It will eventually return the return value of the method, or it will throw an exception if the method threw an exception.
To fetch and render the data meteor way you have to use the package called react-meteor-data to create createContainer.
For example if you were to use it then you would be able to pass it directly to the component as props.
export default createContainer((props) => {
Meteor.subscribe('questions');
return {
questions: Questions.findOne({_id: props.match.params.id})
};
}, QuestionDo);