Fetch GraphQL data based on variable - vue.js

I am trying to get my query to react to a ref property.
https://v4.apollo.vuejs.org/guide-composable/query.html#variables
This wont work at all
const { result, variables } = useQuery(gql`
query {
episodes(page: $page) {
info {
pages
count
}
results {
name
}
}
}
`, {
page: 2
});
Tried this as well
setup() {
const currentPage = ref(1);
const { result } = useQuery(gql`
query {
episodes(page: ${currentPage.value}) {
info {
pages
count
}
results {
name
}
}
}
`);
function pageChange() {
currentPage.value += 1;
console.log(currentPage.value)
}
return { result, currentPage, pageChange };
},
This code below works for me when I input page number manually, but I want to pass the page number as variable, because my pagination page increases and I want the query to refresh.
const { result, loading } = useQuery(gql`
query {
episodes(page: 2) {
info {
pages
count
}
results {
name
}
}
}
`,
);
Can someone assist me?

In the link you gave query is followed by the query name.
const { result } = useQuery(gql`
query getUserById ($id: ID!) {
user (id: $id) {
id
email
}
}
`, {
id: 'abc-abc-abc',
})
You don’t specify the query name
Try this instead:
const { result, variables } = useQuery(gql`
query episodes($page: Int) {
episodes(page: $page) {
info {
pages
count
}
results {
name
}
}
}
`, {
page: 2
});
I don’t know what’s your schema looks like but I inferred that page is a Int. If it’s not change Int by the page type

Related

How to access parameter from graphql query

Using DatoCMS, with VueJS and gridsome. The page query looks like
<page-query>
{
DatoCms {
_site {
globalSeo {
facebookPageUrl
siteName
titleSuffix
twitterAccount
fallbackSeo {
description
title
twitterCard
image {
url
}
}
}
}
}
}
</page-query>
Below does not work to get the values from the query
export default {
metaInfo: {
title: this.$page.DatoCms._site[0].globalSeo.fallbackSeo.title,
the query needed to be adjusted and metainfo method updated

Reactive query definition with Apollo and Vuejs

i try to call a query programaticly eg:
apollo: {
listItems: {
query() {
if (this.listType == "bills") {
return gql`
{
bills {
billId
order {
orderId
customer {
customerId
billingAddress {
title
}
}
}
createdAt
}
}
`;
}
},
property
update: data => data.bills || data.bills
}
}
but when i try this, i get this error:
vue.runtime.esm.js?2b0e:1888 Invariant Violation: Expecting a parsed GraphQL document. Perhaps you need to wrap the query string in a "gql" tag?
I have follow the description in the docs:
https://apollo.vuejs.org/guide/apollo/queries.html#reactive-query-definition
Best regards and thanks four help!
Stay healthy
You cannot wrap apollo query in an if statement. You can use skip instead. In your example it would be like this:
listItems: {
query() {
return gql`
{
bills {
billId
order {
orderId
customer {
customerId
billingAddress {
title
}
}
}
createdAt
}
}`
},
skip() {
return this.listType != "bills"
}
}

Detox get length of element

Hi i'm using detox and i would like to know how can I get the number of matches to
one element(length).
For example "card" match three times, how can I get the three.
const z = await element(by.id("card"))
https://github.com/wix/Detox/blob/master/docs/APIRef.Expect.md
https://github.com/wix/Detox/blob/master/docs/APIRef.Matchers.md
They don't support it in the API /:
z output:
Element {
_invocationManager: InvocationManager {
executionHandler: Client {
isConnected: true,
configuration: [Object],
ws: [AsyncWebSocket],
slowInvocationStatusHandler: null,
slowInvocationTimeout: undefined,
successfulTestRun: true,
pandingAppCrash: undefined
}
},
matcher: Matcher { predicate: { type: 'id', value: 'card' } }
}
A workaround could be
async function getMatchesLength(elID) {
let index = 0;
try {
while (true) {
await expect(element(by.id(elID)).atIndex(index)).toExist();
index++;
}
} catch (error) {
console.log('find ', index, 'matches');
}
return index;
}
then you can use
const length = await getMatchesLength('card');
jestExpect(length).toBe(3);
Here is my solution in typescript:
async function elementCount(matcher: Detox.NativeMatcher) {
const attributes = await element(matcher).getAttributes();
// If the query matches multiple elements, the attributes of all matched elements is returned as an array of objects under the elements key.
https://wix.github.io/Detox/docs/api/actions-on-element/#getattributes
if ("elements" in attributes) {
return attributes.elements.length;
} else {
return 1;
}
}
Then you can use it like this:
const jestExpect = require("expect");
jestExpect(await elementCount(by.id("some-id"))).toBe(2);

Custom directive to check list length for input types

I tried my best to write a custom directive in apollo server express to validate if an input type field of type [Int] does not have more than max length but do not know if its the right way to do. Appreciate if somebody could help me correct any mistakes in the code below.
// schema.js
directive #listLength(max: Int) on INPUT_FIELD_DEFINITION
input FiltersInput {
filters: Filters
}
input Filters {
keys: [Int] #listLength(max: 10000)
}
// Custom directive
const { SchemaDirectiveVisitor } = require('apollo-server-express');
import {
GraphQLList,
GraphQLScalarType,
GraphQLInt,
Kind,
DirectiveLocation,
GraphQLDirective
} from "graphql";
export class ListLengthDirective extends SchemaDirectiveVisitor {
static getDirectiveDeclaration(directiveName) {
return new GraphQLDirective({
name: directiveName,
locations: [DirectiveLocation.INPUT_FIELD_DEFINITION],
args: {
max: { type: GraphQLInt },
}
});
}
// Replace field.type with a custom GraphQLScalarType that enforces the
// length restriction.
wrapType(field) {
const fieldName = field.astNode.name.value;
const { type } = field;
if (field.type instanceof GraphQLList) {
field.type = new LimitedLengthType(fieldName, type, this.args.max);
} else {
throw new Error(`Not a scalar type: ${field.type}`);
}
}
visitInputFieldDefinition(field) {
this.wrapType(field);
}
}
class LimitedLengthType extends GraphQLScalarType {
constructor(name, type, maxLength) {
super({
name,
serialize(value) {
return type.serialize(value);
},
parseValue(value) {
value = type.serialize(value);
return type.parseValue(value);
},
parseLiteral(ast) {
switch (ast.kind) {
case Kind.LIST:
if (ast.values.length > maxLength) {
throw {
code: 400,
message: `'${name}' parameter cannot extend ${maxLength} values`,
};
}
const arrayOfInts = ast.values.map(valueObj => parseInt(valueObj['value']));
return arrayOfInts;
}
throw new Error('ast kind should be Int of ListValue')
},
});
}
}
Does this look right?
Thanks

Vue.js | Filters is not return

I have a problem.
I am posting a category id with http post. status is returning a data that is true. I want to return with the value count variable from the back. But count does not go back. Return in function does not work. the value in the function does not return from the outside.
category-index -> View
<td>{{category.id | count}}</td>
Controller File
/**
* #Access(admin=true)
* #Route(methods="POST")
* #Request({"id": "integer"}, csrf=true)
*/
public function countAction($id){
return ['status' => 'yes'];
}
Vue File
filters: {
count: function(data){
var count = '';
this.$http.post('/admin/api/dpnblog/category/count' , {id:data} , function(success){
count = success.status;
}).catch(function(error){
console.log('error')
})
return count;
}
}
But not working :(
Thank you guys.
Note: Since you're using <td> it implies that you have a whole table of these; you might want to consider getting them all at once to reduce the amount of back-end calls.
Filters are meant for simple in-place string modifications like formatting etc.
Consider using a method to fetch this instead.
template
<td>{{ categoryCount }}</td>
script
data() {
return {
categoryCount: ''
}
},
created() {
this.categoryCount = this.fetchCategoryCount()
},
methods: {
async fetchCategoryCount() {
try {
const response = await this.$http.post('/admin/api/dpnblog/category/count', {id: this.category.id})
return response.status;
} catch(error) {
console.error('error')
}
}
}
view
<td>{{count}}</td>
vue
data() {
return {
count: '',
}
},
mounted() {
// or in any other Controller, and set your id this function
this.countFunc()
},
methods: {
countFunc: function(data) {
this.$http
.post('/admin/api/dpnblog/category/count', { id: data }, function(
success,
) {
// update view
this.count = success.status
})
.catch(function(error) {
console.log('error')
})
},
},