All Projects → Astrocoders → bs-reason-apollo

Astrocoders / bs-reason-apollo

Licence: MIT license
ReactApollo bindings for BS

Programming Languages

ocaml
1615 projects

Projects that are alternatives of or similar to bs-reason-apollo

bs-graphql-bindings
BuckleScript binding for graphql-js
Stars: ✭ 50 (+117.39%)
Mutual labels:  apollo, reasonml
Learn Graphql
Real world GraphQL tutorials for frontend developers with deadlines!
Stars: ✭ 586 (+2447.83%)
Mutual labels:  apollo, reasonml
Reason Apollo Hooks
Deprecated in favor of https://github.com/reasonml-community/graphql-ppx
Stars: ✭ 140 (+508.7%)
Mutual labels:  apollo, reasonml
react-chat-app
A real-time chat application with Node.js, Prisma, GraphQL, Next.js, React.js and Apollo.
Stars: ✭ 61 (+165.22%)
Mutual labels:  apollo
bs-react-fela
BuckleScript bindings for react-fela
Stars: ✭ 21 (-8.7%)
Mutual labels:  reasonml
re-use
⚛️ 🎣 A collection of hooks for ReasonReact
Stars: ✭ 27 (+17.39%)
Mutual labels:  reasonml
apollo-fragment
Use Apollo Link State to connect components to GraphQL fragments in the Apollo Cache
Stars: ✭ 112 (+386.96%)
Mutual labels:  apollo
webpack-everything
Vue cli template with webpack, vuex, vue router, eslint, image compression, graphql, apollo, server side rendering, code splitting and progressive web app (PWA) capabilities
Stars: ✭ 19 (-17.39%)
Mutual labels:  apollo
re-typescript
An opinionated attempt at finally solving typescript interop for ReasonML / OCaml.
Stars: ✭ 68 (+195.65%)
Mutual labels:  reasonml
spring-boot-apollo-sample
Demo project for Spring Boot Apollo
Stars: ✭ 22 (-4.35%)
Mutual labels:  apollo
corporate-dashboard
🔥 A blazingly fast corporate dashboard single page web application, built with a focus on component oriented design with React, Relay & GraphQL
Stars: ✭ 52 (+126.09%)
Mutual labels:  apollo
ios-graphql
iOS code examples with GraphQL, Apollo & more
Stars: ✭ 78 (+239.13%)
Mutual labels:  apollo
nuxtjs-woocommerce
NuxtJS (Vue) eCommerce site with WooCommerce backend
Stars: ✭ 83 (+260.87%)
Mutual labels:  apollo
spring-boot-learn-box
spring boot集成其他组件
Stars: ✭ 21 (-8.7%)
Mutual labels:  apollo
tea-chess
A chess-themed tutorial on writing an SPA in Bucklescript-TEA
Stars: ✭ 28 (+21.74%)
Mutual labels:  reasonml
serverless-reasonml
serverless framework plugin for writing functions with Reason
Stars: ✭ 13 (-43.48%)
Mutual labels:  reasonml
nibbledb
a byte-sized time series database
Stars: ✭ 23 (+0%)
Mutual labels:  reasonml
downwrite
✍️ Markdown writing application that's down right, neat.
Stars: ✭ 103 (+347.83%)
Mutual labels:  apollo
reason-cookie
A simple way to use cookies in Reason (OCaml) on the frontend. 🍪
Stars: ✭ 18 (-21.74%)
Mutual labels:  reasonml
nap
[Deprecated] NextJS + Apollo + PassportJS
Stars: ✭ 52 (+126.09%)
Mutual labels:  apollo

Deprecated

bs-reason-apollo

Build Status

Initially inspired by https://github.com/FormidableLabs/seattlejsconf-app/blob/master/re/types/ReactApollo.re But now with a more sugared usage with function as child.

Why it got deprecated?

The only reason we built this in the first place was because we needed a way to make the transition with the current Apollo setup we had. Now the official Reason Apollo bindings allows you to use any Apollo client instance from React context.

Install

yarn add bs-reason-apollo

Update your bs-config.json

  "bs-dependencies": ["reason-react", "bs-reform", "bs-reason-apollo"],

ReactApollo.CreateWrapper

As you have your ApolloProvider somewhere in the top of your React JS tree you are already covered there. So now to use it with Apollo create a query definition module for you query:

/* re/SignInQueryGql.re */
open BsReasonApollo;

let query = GraphQLTag.gql({|
  query SignInQuery {
    currentUser {
      id
      email
    }
  }
|});

module Types = {
  type user = {. "id": string, "email": string};
  type error = {. "message": string};
  /* You must always have this data type with loading and error, it's what the HOC gives you */
  type data = {
    .
    "loading": Js.boolean,
    "error": Js.null_undefined(error),
    /* Our response */
    "currentUser": Js.null_undefined(user)
  };
};

type data = Types.data;

/* Define any Js.t variables that you query need here, if you don't use just declare it */
type variables;

type response = Types.user;

Now in your actually component:

open BsReasonApollo;

module SignInQueryWrapper = ReactApollo.CreateWrapper(SignInQueryGql);

...
let make = (_children) => {
  ...,
  render: (_self) =>
    <SignInQueryWrapper>
    ...((~data) =>
        switch (
          Js.to_bool(data##loading),
          Js.Null_undefined.to_opt(data##error),
          Js.Null_undefined.to_opt(data##currentUser)
        ) {
        | (true, _, _) => <FullLoading />
        | (false, _, Some(user)) =>
          <Welcome user />
        | (false, Some(error), _) => <Whoops name=error##message />
        | (false, None, _) =>
          <KeyboardAwareScrollView>
            <Wrapper>
              <Header>
                <Logo
                  source=Image.(
                           Required(Packager.require("../../../src/public/img/logo-calendar.png"))
                         )
                />
              </Header>
              <ContentWrapper
                contentContainerStyle=Style.(
                                        style([
                                          paddingVertical(Pt(40.)),
                                          justifyContent(SpaceAround)
                                        ])
                                      )>
                <SignInForm />
              </ContentWrapper>
            </Wrapper>
          </KeyboardAwareScrollView>
        }
      )
    </SignInQueryWrapper>
}

ReactApollo.CreateMutationWrapper

Define the mutation module:

/* re/SignInMutationGql.re */
open BsReasonApollo;

let query = GraphQLTag.gql({|
  mutation SignInQuery($input: SignInInput!) {
    signIn(input: $input) {
      error
      token
    }
  }
|});

module Types = {
  type input = {. "password": string, "email": string};
  type signIn = {. "error": Js.null_undefined(string), "token": Js.null_undefined(string)};
};

/* Needed for mutations, it'll be probably `variables` in the next release */
type input = Types.input;

/* Mutation response */
type response = {. "signIn": Types.signIn};
open BsReasonApollo;

/* Mutation wrapper */
module SignInMutationWrapper = ReactApollo.CreateMutationWrapper(SignInQueryGql);

/* https://github.com/Astrocoders/reform */
module SignInForm = ReForm.Create(SignInFormParams);

let convertInputToJs: SignInFormParams.state => SignInMutationGql.Types.signInInput =
  (values) => {"password": values.password, "email": values.email};

let handleSubmit = (mutate, values, setSubmitting) =>
  values
  |> convertToJs
  |> mutate
  |> Js.Promise.(
       then_(
         (payload) =>
           (
             switch (Js.Null_undefined.to_opt(payload##signIn##error)) {
             | Some(error) =>
               Alert.alert(~title="Something went wrong", ~message=error, ());
               setSubmitting(false)
             | None =>
               RouterActions.home(~actionType=`replace);
               let _ =
                 Utils.UserSession.setToken(
                   Utils.get(Js.Null_undefined.to_opt(payload##signIn##token), "")
                 );
               ignore()
             }
           )
           |> resolve
       )
     )
  |> ignore;

/* A little abstraction to make function as child composition hurt a bit less */
let enhanced = (mapper) => {
  <SignInMutationWrapper>
    ...((~mutate) => (
      <SignInForm
        initialValues={etc}
         onSubmit=(
           (values, ~setSubmitting, ~setError as _) =>
             handleSubmit(mutate, values, setSubmitting)
         )
      >
        ...mapper
      </SignInForm>
    ))
  </SignInMutationWrapper>
};

let component =

Demo

WIP

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].