Enum for number in GraphQL (js) - graphql

I want to allow one of the fields to be either 1, 2 or 3. I am not exactly sure how to do that in http://graphql.org/graphql-js/type/
Because I would need to do something like:
var AgeType = new GraphQLEnumType({
name: 'Age',
values: {
1: { value: 0 },
2: { value: 1 },
3: { value: 2 }
}
});
And this doesn't work because the key is a number...

It's not possible as described here: https://github.com/graphql/graphiql/issues/586
GraphQL require enum values to match [_A-Za-z][_0-9A-Za-z] RegExp
Enum variables have to start with a letter, so you will have to use String or Int type. In order to ensure that only 1,2 and 3 are passed, you may implement some kind of validation rules in the resolvers.

Related

How to make inputs more DRY in React Apollo?

How can I reuse variable arguments in GQL Apollo React? e.g. in a situation where the inputs are the same but we need different data corresponding for a different situation.
Is there a way to define this inside or outside of this query call?
const REQUEST_1 = gql`
query QueryA(
$page: Int
$a: String
$b: Number
$etc: EtcFilter
) {
getData(
limit: 24
page: $page
a: $a
b: $b
etc: $etc
) {
total
result {
id
time
location
}
}
}
`
const REQUEST_2 = gql`
query QueryA(
$page: Int
$a: String
$b: Number
$etc: EtcFilter
) {
getData(
limit: 24
page: $page
a: $a
b: $b
etc: $etc
) {
total
result {
postContent
date
coordinates
id
}
}
}
`
Based on your Query example, the short/sad answer is you cannot do that.
According to the current GraphQL specs:
Variables must be defined at the top of an operation and are in scope throughout the execution of that operation.
That operation is referring to a query/mutation, in your example, REQUEST_1 and REQUEST_2 are two separate operations.
There is an open issue in the graphql-specs that could possible address this use case, but it is not anywhere near implementation.
Edit with one operation example (from comments)
You could combine both operations in one, in something like this:
const REQUEST = gql`
query QueryA(
$page: Int
$a: String
$b: Number
$etc: EtcFilter
) {
getData(
limit: 24
page: $page
a: $a
b: $b
etc: $etc
) {
total
result1: result {
id
time
location
}
result2: result {
postContent
date
coordinates
id
}
}
}
`
because you would be querying the same result object just with different fields, you will have to give an alias to it.
This will of course make the full query every time, but it will keep it cleaner of input parameters.

amount of character which are between epiosde 1 and 2 with the name Rick

I have a problem. I am using the https://rickandmortyapi.com/graphql API for graphql. I want to query the amount of character which are between epiosde 1 and 2 with the name Rick. Unfortunately my query is wrong. How could I get the desired output. I want to use the _" ..."Meta to get the meta data.
query {
characters(filter: {name: "Rick"}) {
_episode(filter: {id : 1
id: 2}) {
count
}
}
}

MongoDB Query if (Field A - Field B) > N

I have been stuck on this for several hours now. I need to write a query that returns all documents where (Field A - Field B) > N
// sample data
{ _id: '...', estimated_hours: 0, actual_hours: 0 },
{ _id: '...', estimated_hours: 10, actual_hours: 9 },
{ _id: '...', estimated_hours: 20, actual_hours: 30 }
Borrowing answers from this stack question I wrote the below, In my mind this should have worked, however I am consistently getting records back that do not match the query...
## Attempt 1
n = 0
records = API::Record.where('$where': "(this.estimated_hours - this.actual_hours) > #{n}")
## should return the following, but im getting additional records
#=> [{ _id: '...', estimated_hours: 10, actual_hours: 9 }]
I know I can likely accomplish this with $project however i have to explicitly tell $project what fields I want returned. I need all the fields to be returned, we use a third party library that handles pagination
play
db.collection.find({
$where: "(this.estimated_hours - this.actual_hours) > 1"
})
Similar example for reference

Inconsistent Alphanumeric Sorting with ag-grid and String Cells [duplicate]

This question already has answers here:
How to make sorting key insensitive in ag-grid?
(3 answers)
Closed 3 years ago.
Im using ag-grid-react to display a table of data from an endpoint. I have a column which contains alphanumeric values which needs to be sortable using a "natural" sort algorithm (i.e. numbers are grouped together, alphanumeric strings are grouped together...)
Below is my column definition. Sorting is enabled on the grid, and when I click the column to sort the grid, everything appears sorted except for some strings which start with a numeral that interrupt the sequence of strings beginning with C.
This happens with ag-grid's default sorting algorithm, regardless of whether or not accentedSort is true or false, and even with a basic custom sort comparator (see below.)
Column Definition:
field: 'cqttUnitPayItemDescriptionId',
headerName: 'Description',
type: 'dropdown',
editable: true,
resizable: true,
valueGetter: (p) => {
const value = p.data[p.colDef.field];
const cellDescription = p.data.description;
// returns a string value for display
// `items` is an ImmutableJs Map of objects, grouped by index, containing a `description` string property.
return value >= 0 ? items.getIn([value, 'description']) || cellDescription : value;
},
cellEditorFramework: AgGridCellEditor({ component: AgDropdownEditor, renderProps: innerProps => ({ createable: true, labelProperty: 'description', options: itemsByUnitPayItemId.getIn([innerProps.data.unitPayItemId], Map()).toList(), ...innerProps }) }),
sortable: true,
width: 250,
comparator: StringComparator
},
Custom Sort Comparator:
export function StringComparator(valueA: string = '', valueB: string = '') {
const valueALower = valueA.toLowerCase();
const valueBLower = valueB.toLowerCase();
return valueALower.localeCompare(valueBLower, 'en', { numeric: true });
}
Visual Example of the Sorting Inconsistencies:
Given the screenshot above: Manual testing of the comparator shows that the string "4' x 8' x 16' (Dragline Mat)" should come before "Construction Crew "Move Around" - Tie-Ins" (i.e. the return value of calling the comparator with those arguments respectively is -1) but clearly the grid thinks otherwise. Could it be I'm missing something regarding the scope of calls to the comparator function?
Turns out some of the strings that were being sorted contained a space at the very beginning of the strings, causing them to (properly) be sorted before numerals and alphabetical characters altogether. I've solved this issue by simply appending .trim() to the end of each value being compared in the StringComparator:
export function StringComparator(valueA: string = '', valueB: string = '') {
const valueALower = valueA.toLowerCase().trim();
const valueBLower = valueB.toLowerCase().trim();
return valueALower.localeCompare(valueBLower, 'en', { numeric: true });
}

How to declare strings in enum

With graphql, enum can make a predefined list of elements but strings don't work.
For example:
enum Dias {
lunes
martes
miércoles
jueves
viernes
sábado
domingo
}
This returns an error GraphQLError: Syntax Error: Cannot parse the unexpected character "\u00E9".
how is it possible to make a predefined list of strings?
Edit: to give more context, I want to reflect the database schema, which is like this (with mongoose):
dias: {
type: String,
enum: ['lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado', 'domingo'],
lowercase: true,
required: true
}
Your syntax is correct, the only issue is that the "é" and "á" characters are not supported. The specification outlines rules for naming operations, fields, etc. The supported pattern is:
/[_A-Za-z][_0-9A-Za-z]*/
Furthermore:
Names in GraphQL are limited to this ASCII subset of possible characters to support interoperation with as many other systems as possible.
So, unfortunately, you will have to convert those accented characters to valid ones in order for your schema to be considered valid.
EDIT: You could create a custom scalar. Here's a function that takes a name, description and an array and returns a custom scalar:
const makeCustomEnumScalar = (name, description, validValues) => {
const checkValue = (value) => {
const coerced = String(value)
if (!validValues.includes(coerced)) {
throw new TypeError(`${coerced} is not a valid value for scalar ${name}`)
}
return coerced
}
return new GraphQLScalarType({
name,
description,
serialize: checkValue,
parseValue: checkValue,
parseLiteral: (ast) => checkValue(ast.value),
})
}
Now you can do something like:
const DayOfWeek = makeCustomEnumScalar('Day of Week', 'day of week enum', [
'lunes',
'martes',
'miércoles',
'jueves',
'viernes',
'sábado',
'domingo'
])
Add it to your resolvers:
const resolvers = {
DayOfWeek,
// Query, Mutation, etc.
}
And your type definitions:
scalar DayOfWeek
And then you can use it like any other scalar. If an invalid value is provided as an input or output by a query, then GraphQL will throw an error like with an enum. The only caveat is that if you're entering the values directly into your query (as opposed to using variables), you'll still need to wrap them in double quotes.

Resources