0

I'll start off by saying, I have been struggling for longer than my pride wants to admit and have put off asking, because I'm not sure how clear I will be; but, here goes . . .

I am using Angular 9 with Apollo-Angular and have no trouble accessing GraphQL queries with either no variables or only one. If I add more than one, I am absolutely unsuccessful. I have created a simple service that will allow me to create dynamic queries, so I have a type for variables that looks like this: enter image description here

Apollo-Angular client looks at it as the type shown in next image. From everything I can see in the documentation, Apollo-Angular should be able to take any given object and convert it proper for the execution of the query, but again…I have yet to make this happen proper with more than one variable. enter image description here

When calling the query, it looks like this:

enter image description here

Which results in the following output in the debug console:

GraphQLQueryVariables {first: 5, order_by: "accountNumber.ASC"}
{"first":5,"order_by":"accountNumber.ASC"}
Error Message Notification: Error: GraphQL error: Variable `$order_by` got invalid value.

From Chrome, this is what is being executed: enter image description here

If I copy the exact same shown in Chrome, into the GraphQL Playground, it returns “Variable couldn’t be parsed. Please go to the variable editor and fix syntax issues”

I have tried for hours trying to send different ways via the WatchQuery variables property. If I try to send the multiple variables as a string using JSON.stringify it shows like this in Chrome: enter image description here enter image description here

If I literally hand type in a static value, I get the same issue from the beginning, “Variables couldn’t be parsed…”

enter image description here

If I run the exact same thing in the playground…but simply add the quotation marks (which are not showing in Chrome), I am successful:

enter image description here

From what I can see, no matter how I send it from the Appllo-Angular Query Watch variable property, I can’t get it to send proper. The ONLY time it sends proper is if I only use ONE variable and that variable happens to be an integer.

Is there an alternative approach I could/should take? Am I just doing this absolute incorrectly??

My specific questions are using Angular & Apollo-Angular:

  1. How do I send multiple variables for the GraphQL query (first, order_by, where, etc)?
  2. How do I send multiple items within one of those variables (ex: "order_by" : "customerName.ASC, accountNumber.DESC, startDate.DESC")?

EDIT: I've just found this in the GraphQL Specs that says:

    Variables Are Input Types
    Formal Specification

    For every operation in a document
    For every variable on each operation
    Let variableType be the type of variable
    IsInputType(variableType) must be true
    Variables can only be input types. Objects, unions, and interfaces cannot be used as inputs

I'm thinking this means I need to add an InputType in the backend (.net core, EF.core & Hot Chocolate) that will generate an Input Type within the schema. I haven't figured it out yet, but at least have given a new path to venture down.

EDIT: Each of my types has one of these used for variables (the only thing that will change is what is in the brackets "Get[AVOs]Variables", "[AVO]Sort", "[AVO]Filter"

export interface GetAVOsVariables {
    order_by?: AVOSort | null;
    first?: any | null;
    last?: any | null;
    after?: string | null;
    before?: string | null;
    where?: AVOFilter | null;
  } 

The "[x]Sort" is a string that is: [fieldName].ASC or [fieldName].DESC regardless of the type. Filter works similar. I am wanting to get the most generic, reusable version created as possible to prevent cloning same code structures simply to change the type name.

EDIT: I was able to get the variables working properly by writing it this way, rather than just trying to send the object in a single line:

this.result = this.apollo.watchQuery<GraphQLResponse>({
    query: gql`${this.query}`,
    variables: {
        first: this.graphRequest.variables.first,
        last: this.graphRequest.variables.last,
        before: this.graphRequest.variables.before,
        after: this.graphRequest.variables.after,
        where: this.graphRequest.variables.where,
        order_by: this.graphRequest.variables.order_by
    } 
  }).valueChanges
    .pipe(map(({data}) => data));
    return this.result;
}
Briana Finney
  • 1,171
  • 5
  • 12
  • 22
  • why `class`? use `interface` – xadm Apr 14 '20 at 20:02
  • I have what was generated (full of interfaces) and the variables are all exactly the same with 2 things different as they are strongly tied to the type. So, if I have 20 types...they all have the same variables...but the order_by will by "TypeASort" and the where will be "TypeAFilter" . I'm trying to get this as generic as possible so I don't have to create multiple copies of essentially same thing. – Briana Finney Apr 14 '20 at 20:29
  • make it working, optimize later? compare network requests in dev tools – xadm Apr 14 '20 at 20:32
  • just use one universal name? you can reuse this for many types – xadm Apr 14 '20 at 21:26
  • Sounds great. Kind of what I'm trying for...but don't know how. Framework that generates the schema has it as strongly typed as possible and I don't know how to change that. Perhaps I need to look more into it and see if I can use Fragments somehow for the variable inputs and it changes that schema being used within Angular. – Briana Finney Apr 14 '20 at 21:41
  • you can "filter out"/"preprocess" generated type definition file... but is it worth the effort? battle for a few kB? drop Angular, use React (with or without typescript), save more, get more flexibility, stability... etc. – xadm Apr 14 '20 at 21:47
  • project is way too grown to change from Angular. I don't want to have to rewrite/clone the same code for every type that wants to GraphQL, with a simple difference of a few characters. I've already got it working to dynamically create the queries with the request types and desired columns. It's just the variables I can't get working the way I want. I'll look into the preprocessing...hopefully that will produce what I'm looking for. Thank you @xadm – Briana Finney Apr 14 '20 at 21:53
  • this types are more typescript requirements then graphql - graphql will work with with any jsoned object (without type informations) ... you can remove all input types definitions and use own one/few .... preprocessing=search and replace (with empty) – xadm Apr 14 '20 at 22:08
  • If you still need help with this we have a slack channel for hot chocolate. – Michael Ingmar Staib Jun 23 '20 at 11:38

0 Answers0