urql-custom-scalars-exchange icon indicating copy to clipboard operation
urql-custom-scalars-exchange copied to clipboard

Handle not only queries but also mutations?

Open RIP21 opened this issue 3 years ago • 2 comments

What I want is to set up not only how I want to process custom scalars, let say, parsing timestamps to Date in a centralized manner. But I would also be happy to make Timestamp as an input field to get transformed from Javascript Date into milliseconds hence the Timestamp that backend expects.

Something like

scalarExchange({
          schema: (schema as unknown) as IntrospectionQuery,
          requestScalars: { // This is how to deserialize it back to original answer that server expects
            Timestamp: (input: Date) => {
              return input.getTime()
            },
            Date: (input: Date) => {
              return format(input, 'YYYY-MM-DD')
            },
            DateTime: (input: Date) => {
              return input // this one can be omited as Urql will run .toString() on this one anyway
            },
          }
          responseScalars: { // This is how to handle them when they come FROM server
            Timestamp: (input: number) => {
              return new Date(input)
            },
            Date: (input: string) => {
              return Date(input)
            },
            DateTime: (input: string) => {
              return Date(input)
            },
          },
        })

This one will make it super good to work with. Especially with graphql-codegen that gives the ability to specify scalar types in TypeScript, so if you map Date from GraphQL into Date on TS side and then, you can serialize it using this extension and be super happy with it when reading (when Fragments will be supported tho as they're not now (issue alongside)), but when you then try to send/write in using mutation some field of type Date and pass JS Date then you'll get a validation error as it will be converted to UTC string with time and timezone and not just YYYY-MM-DD causing you a headache :)

If this logic above will be implemented then it will be an amazing experience.

Please! :)

RIP21 avatar Dec 26 '20 02:12 RIP21

is anyone working on this?

callmeberzerker avatar Jun 02 '21 06:06 callmeberzerker

I am very new in graphql and i also have this problem. When i am using graphql-codegen my custom scalars classes are used as in query results as in query parameters, so correct serialization is needed to make ot workable. I see the workaround based on implementation of stringify method in urql

function stringify(e) {
  if (null === e || i.has(e)) {
    return "null";
  } else if ("object" != typeof e) {
    return JSON.stringify(e) || "";
  } else if (e.toJSON) {
    return stringify(e.toJSON());
  } else if (Array.isArray(e)) {
    var r = "[";
    for (var t = 0, n = e.length; t < n; t++) {
      if (t > 0) {
        r += ",";
      }
      var o = stringify(e[t]);
      r += o.length > 0 ? o : "null";
    }
    return r += "]";
  }

It means you could implement method toJSON method in your Custom scalar class to serialize data back. Not sure is it done by design or works by accident. The toJSON method is available for Date class.

dmytro-shpak avatar Nov 19 '21 12:11 dmytro-shpak