GraphQL error: Expected type Int. Int cannot represent non-integer value - reactjs

I'm currently learning GraphQL with Apollo for React and I have a question that I can't find the answer online:
I've done a form to send data for my mongoDB and I have this query:
const addContactMutation = gql`
mutation($name: String!, $address: String!, $vat: Int!, $zip: String!, $email: String!, $contact: Int!){
addContact(name: $name, address: $address, vat: $vat, zip: $zip, email: $email, contact: $contact){
name
vat
email
}
}
`
However, my $vat and $contact are big numbers and when submit the form I receive this error:
Variable "$vat" got invalid value "232214336"; Expected type Int. Int cannot represent non-integer value
Which type should I use for that?

232214336 is not so big, the max int number is 9007199254740991
console.log(Number.MAX_SAFE_INTEGER);
I think the problem is you've passed a string value "232214336" when an Int value is expected as the error says Expected type Int, so you need to convert the value to an integer before or when passing variables to the mutation using parseInt()
addContact({ variables: { vat: parseInt(vat, 10), contact: parseInt(contact, 10), ... } })

This error also happens when a database field that is typed as an integer, contains a value of NULL, and that field is returned by your GraphQL query. One way to fix this, is to set up your database to give integer fields a default value so that they are never NULL when the row is created.

I faced this problem before and I resolved it by :
first I checked if the order of types in the front-end is the same as in graphql-types
then
in the input form I replaced: target.value
by: target.valueAsNumber

I also encountered a similar and weird kind of issue, as types were mentioned clearly but that wasn't accepted in variables by graphql-request version 3.1.4, I mapped them again in a variable that is working at my end so far.
const variables = {
orderId: +orderId,
vendorIds: vendorIds.map(id => +id),
};

I got the same error in my Grapql+NestJs application. What I did is changed the graph field type from Int to Float. It works

Related

react-location useSearch return number instead of strings

I am using react 18 and react-location. I save some filter in the URL, and they are type string but effectively a number like "38" so url looks like id=32
Now, when I use
const search = useSearch<MakeGenerics<{ Search: { id: string } }>>();
what I actually get in code is a number 38 and not my string "38".
But I never asked react-location to actually convert my search parameters to a number, what I want is to get the string as my type is suggesting.
is there a way to avoid this behavior ?

Compare two customised fields in Yup validation

I need to compare two number fields. AreaTo must be bigger than AreaFrom. It works this way:
area_to: Yup.number().min(
Yup.ref("area_from"),
`AreaTo should be bigger than AreaFrom`
),
The problem is I also use custom number formatting in this fields, that returns string, so the field type should be not number but string. But min() is not usable with the strings. I have a function parseNumber(str) that parse number from that string. So I need something like:
area_to: parseNumber(Yup.string()).min(
Yup.ref("area_from"),
`AreaTo should be bigger than AreaFrom`
),
But obviously it don’t work that way. Please help me to implement it properly.
I think you'd want to use test(), and pass in testContext, to reference the other field's value via testContext.parent:
const validationSchema = Yup.object().shape({
area_from: Yup.number().isRequired('Required'),
area_to: Yup.mixed().test('isLarger', 'area_to must be larger than area_from', (value, testContext) => {
if (testContext.parent.area_from > value) return false
return true
})
})
You can read the documentation on this feature here.
At the end this solution worked as expected:
area_to: Yup.string().test(
"area_compare",
`area_to must be bigger then area_from`,
function (area_to: string | undefined): boolean {
return area_to
? parseNumber(area_to) > parseNumber(this.parent.area_from)
: true;
}
),

Typescript Error: Argument of type 'NodeListOf<HTMLInputElement> | undefined' is not assignable to parameter of type 'Iterable<HTMLInputElement> ..."

In my React/Typescript App, I am accessing an array of inputs in an event listener through using 'e.currentTarget'. I am using Array.from() to convert the NodeListOf into an array, and made sure to configure my TS.config.json settings of 'es2015'. However I'm receiving this error.
Error
Oddly, this error doesn't occur in my original directory. I had duplicated my project folder, deleted node modules, zipped it, and reopened it, and that's when this error occurs. Not quite sure how else to approach this issue, if anyone has suggestions or solutions, it'd be appreciated.
e: React.ChangeEvent<HTMLInputElement> | React.KeyboardEvent<Element>,
letter: string,
idx: number,
) => {
const fields: HTMLInputElement[] = Array.from(
e.currentTarget.parentElement?.parentElement?.querySelectorAll('input')
)
const length: number = fields.length
const position: number = fields.indexOf(e.target)
You didn't provide much code, but my guess is this is happening because e.currentTarget.parentElement?.parentElement?.querySelectorAll('input') could potentially be undefined. undefined cannot be used as the argument for Array.from, as undefined is not iterable. You need to make sure it exists before you feed it to Array.from. Two possible solutions:
Check that the NodeList you're targeting really exists, then assign your variable
if (document.querySelector('.maybe')?.parentElement?.querySelectorAll('.doesnt-exist?')) {
const fields = Array.from(document.querySelector('.maybe')!.parentElement!.querySelectorAll('.doesnt-exist?'))
}
Assign your potential NodeList to a variable, but default it to [], just in case. Autocast that variable as an HTMLInputElement[], and then it can be safely used in Array.from:
const checker =
document.querySelector('.maybe')?.parentElement?.querySelectorAll('.doesnt-exist?') ?? [] as HTMLInputElement[]
const fields: Element[] = Array.from(checker)
TS Playground

Argument of type 'string' is not assignable to parameter of type '`${string}` | `${string}.${string}` | `${string}.${number}`'

I've migrated react-hook-forms from v.6 to v.7.
After changing the register method, as pointed out in the migration guide, the following error occurs:
Argument of type 'string' is not assignable to parameter of type '${string} | ${string}.${string} | ${string}.${number}'. TS2345
Register expects a string name, which I provide correctly with a param which for sure is a string, but anyhow it doesn't accept my parameter if I don't pass exactly string.
Anyone with a similar issue or any idea is highly appreciated. Thanks in advance!
register() in react-hook-form v7 does not accept a string but string literal. The literal value is one of the field name in the form:
interface IFormValues {
firstName: string;
lastName: string;
}
const { register, handleSubmit } = useForm<IFormValues>();
When you assign a generic type parameter to the useForm hook, the register expects to receive either firstName or lastName literal, a string or anything else will throw a type error.
Solution
According to the official example, if you are using useFieldArray and the fields are created dynamically using map, you need to assert the name as a const before passing to the register, this is because of type widening when you mix string literal with the index number:
<input key={field.id} {...register(`test.${index}.test` as const)} />

Convert NUMERIC to VARCHAR using sequelize model

I have this NUMERIC(20) field on mssql and I'm trying do read it as a data type string to get the full number because int limits on javascript
code: {
type: DataTypes.STRING
}
But the returned value is a truncated INT
[ {code: 4216113112911594000 } ]
No matter what kind of data type choose it'll return as truncated int
The original values is 4216113112911594192. This is a java UUID
How can a convert this value to using model.findAll()
This is a already created table for another application and I'm trying to read it using sequelize
Here you go :
code: {
type: Sequelize.INTEGER , // <------ keep is as DB's datatype
get() { // <------ Use getter method to modify the output of query
return this.getDataValue('code').toString();
}
}
I think this might help you
model.findOne({
attributes: [[db.sequelize.literal('cast(`code` as varchar)'), 'code_string']] ,
where : { id : YOUR_ID }
}).then(data => {
console.log(data); // <------ Check your output here
})
I have not fully understood what you are trying to achieve.
Nor my code is tested.
Idea 1 : convert into float.
Idea 2 : Append any string alphabet to originial int value before sending to javascript.
The original values is 4216113112911594192.
So the string become 'A'+'4216113112911594192'='A4216113112911594192'
Now you can play with 'A4216113112911594192'
There are many javascript library to support big integer.
BigInteger
This worked for postgres (thanks Bessonov & vitaly-t!)
Just add this before you initialize sequelize
import pg from 'pg'
// Parse bigints and bigint arrays
pg.types.setTypeParser(20, BigInt) // Type Id 20 = BIGINT | BIGSERIAL
const parseBigIntArray = pg.types.getTypeParser(1016) // 1016 = Type Id for arrays of BigInt values
pg.types.setTypeParser(1016, (a) => parseBigIntArray(a).map(BigInt))
A little background:
I didn't want Sequelize to parse bigint columns as strings, so I added pg.defaults.parseInt8 = true. That made pg start parsing bigints as regular numbers, but it truncated numbers that were too big. I ended up going with the above solution.

Resources