Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

usage in Node.js without React #155

Open
2 of 5 tasks
tdfairbrother opened this issue Nov 12, 2018 · 7 comments
Open
2 of 5 tasks

usage in Node.js without React #155

tdfairbrother opened this issue Nov 12, 2018 · 7 comments
Labels
docs Focuses on documentation changes feature New addition or enhancement to existing solutions

Comments

@tdfairbrother
Copy link

tdfairbrother commented Nov 12, 2018

Issue Labels

  • has-reproduction
  • feature
  • docs
  • blocking
  • good first issue

How do I query and parse the response of a query without using the React Query component?

React components render to the dom and to strings (for SSR) whereas I just want query and have a parsed reason response that I can work with for a backend task.

I notice that the decoder functions are hidden inside a React component. Is there a way to hook into these?

This has been talked about in #124 and #71 but I don't see any specific answers to bypassing React.

  module MyQuery = [%graphql
   {|
     ...
   |}
  ];

  let q = MyQuery.make(~id, ());
  let queryAst = gql(. q##query);

  let query = Client.instance##query({
    "query": queryAst,
    "variables": q##variables
  })

I have tried...

  query
    |> Js.Promise.then_(value => {
      let data = q##parse(response##data)
      Js.Promise.resolve(data);
    })


 This has type:
    Js.Promise.t(Js.Json.t) => Js.Promise.t(Js.Json.t)
  But somewhere wanted:
    Js.Promise.t(ReasonApolloQuery.renderPropObjJS) => 'a

@ghost ghost added docs Focuses on documentation changes feature New addition or enhancement to existing solutions labels Nov 12, 2018
@tdfairbrother
Copy link
Author

This is what I ended up with. Feel free to close this issue unless there is a preferred way to parse the response.

type response = {
  .
  "data": Js.Nullable.t(Js.Json.t)
};

external toApolloResult: 'a => response = "%identity";

 query
  |> Js.Promise.then_((response) => {
    let apolloData = toApolloResult(response);
    let result = Belt.Option.map(apolloData##data |> Js.Nullable.toOption, q##parse)
    Js.Promise.resolve(result);
  });

@thangngoc89
Copy link

@tdfairbrother This particular project is a binding to react-apollo. though it contains binding to apollo-client, it's not focus on that front. so no way you can avoid react when using this. If all you want is to parse the response, you can use graphql-ppx directly

@tdfairbrother
Copy link
Author

I guess I missed the blurb React-apollo with Reason.

@fakenickels
Copy link
Contributor

This is indeed something, maybe we could split ApolloClient as a different binding which would be dependency to Reason React Apollo

@idkjs
Copy link
Contributor

idkjs commented Feb 13, 2019

@tdfairbrother do you have any more details on how you did this? Maybe an example gist?

Did your create something like a Fetcher component then pass your Query module to it?

For anyone, are you using a separate graphql client in the same project when you dont need react for a specific query?

Thanks for any guidance.

@tdfairbrother
Copy link
Author

tdfairbrother commented Feb 14, 2019

@idkjs here is a complete example

[@bs.module "isomorphic-fetch"] external fetch : ApolloClient.fetch = "";

module Client = {
  open ApolloInMemoryCache;
  let inMemoryCache = createInMemoryCache();
  let uri = Util.getEnvVar("GRAPHQL_URL", "not_set");
  let httpLink = ApolloLinks.createHttpLink(~uri, ~fetch, ());
  let instance =
    ReasonApollo.createApolloClient(~link=httpLink, ~cache=inMemoryCache, ());
}

type response = {. "data": Js.Nullable.t(Js.Json.t)};

external toApolloResult : 'a => response = "%identity";

let query = (q, ast) =>
  Client.instance##query({"query": ast, "variables": q##variables})
  |> Js.Promise.then_(response => {
       let apolloData = toApolloResult(response);
       let result =
         Belt.Option.map(apolloData##data |> Js.Nullable.toOption, q##parse);
       Js.Promise.resolve(result);
     });

module GetVideoQuery = [%graphql
  {|
    query video($videoId: ID!) {
      video(id: $videoId) {
        id
        description
      }
    }
  |}
];

let queryVideo = videoId => {
  let q = GetVideoQuery.make(~videoId, ());
  let videoAST = gql(. q##query);
  query(q, videoAST);
};

@idkjs
Copy link
Contributor

idkjs commented Feb 14, 2019

That is super useful @tdfairbrother. Thank you for sharing.

I was going to try something like this.

module GetAllDogs = [%graphql
  {|
    query dogs {
      dogs {
        name
        breed
        description
      }
    }
  |}
];
/* Construct a "packaged" query; GetAllDogs query takes no arguments: */
let dogsQuery = GetAllDogs.make();

/* Send this query string to the server */
let query = dogsQuery##query;

Axios.get("https://formidadog-ql.now.sh/graphql?query="++query)
    |> Js.Promise.then_(value => {
     let dogs = value##data;
     Js.log2("Dogs", value##data);
     Js.Promise.resolve(dogs);
   })
|> Js.Promise.catch(err => {
     Js.log2("Something went wrong!", err);
     Js.Promise.resolve(err);
})

I have no idea if that would work or not...
Going to try your solution. Will let you know how it goes.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
docs Focuses on documentation changes feature New addition or enhancement to existing solutions
Projects
None yet
Development

No branches or pull requests

4 participants