Search code examples
ocamlgraphqlreasonbucklescriptreason-react

Graphql array response to ReasonReact


Trying to figure working with data in reason. I have this graphql query returning data a logging it. Question is how do I access the data in the following component.

let component = ReasonReact.statelessComponent("Home");

let make = (_) => {
  ...component,
  render: (_self) =>
    <View>
      <Hello message="Hello from home component" />
      <FetchEpisodes>
        (
          (response) => {
            Js.log(response);
            /* let episodeItems =
               Array.of_list(
                 List.map(
                   (response) =>
                     <Episode
                       key=response##data##allEpisodes##id
                       episode=response##data##allEpisodes##episode
                     />,
                 )
               ); */
            <div> <h1> (ReasonReact.stringToElement("Episodes!")) </h1> </div>
            /* (ReasonReact.arrayToElement(episodeItems)) */
          }
        )
      </FetchEpisodes>
    </View>
};

This is the query response: enter image description here

coming from JS i keep wanting to log allEpisodes with some like response.data...which doesn't work here, obviously

Gists to components: episode component, home.re component

If i uncomment and run, it produces the following error:

```

FAILED: src/pages/home.mlast
/usr/local/lib/node_modules/bs-platform/bin/bsc.exe -pp "/usr/local/lib/node_modules/bs-platform/bin/refmt3.exe --print binary" -ppx '/usr/local/lib/node_modules/bs-platform/bin/reactjs_jsx_ppx_2.exe'   -w -30-40+6+7+27+32..39+44+45+101 -nostdlib -I '/Users/shingdev/code/REASON/with-reason-apollo-master/node_modules/bs-platform/lib/ocaml' -bs-super-errors -no-alias-deps -color always -c -o src/pages/home.mlast -bs-syntax-only -bs-binary-ast -impl /Users/shingdev/code/REASON/with-reason-apollo-master/src/pages/home.re
File "/Users/shingdev/code/REASON/with-reason-apollo-master/src/pages/home.re", line 53, characters 17-18:
Error: 2806: <UNKNOWN SYNTAX ERROR>

  We've found a bug for you!
  /Users/shingdev/code/REASON/with-reason-apollo-master/src/pages/home.re

  There's been an error running Reason's refmt parser on a file.
  This was the command:

  /usr/local/lib/node_modules/bs-platform/bin/refmt3.exe --print binary '/Users/shingdev/code/REASON/with-reason-apollo-master/src/pages/home.re' > /var/folders/qx/xhwh5zfj7z36_bjh5187svx00000gn/T/ocamlpp530e68

```

I'm not understanding how to process the response object when an array is returned. Thank you.

UPDATE per @glennsl's suggestion:

```
let make = (_) => {
  ...component,
  render: (_self) =>
    <View>
      <Hello message="Hello from home component" />
      /* <Greeting name="Tony" /> */
      <FetchEpisodes>
        (
          (response) => {
            let episodeItems =
              response##data##allEpisodes
              |> Array.map((episode) => <Episode key=episode##id title=episode##title />);
            <div> <h1> (ReasonReact.stringToElement("Episodes!")) </h1> </div>(
              ReasonReact.arrayToElement(episodeItems)
            )
          }
        )
      </FetchEpisodes>
    </View>
};
```

This produces the following error:

enter image description here

I'm figuring its coming because the types arent being passed to episode.re

```
let component = ReasonReact.statelessComponent("Episode");

let make = (~style=?, ~episode, _children) => {
  ...component,
  render: (_self) => <View ?style> <h1> (ReasonReact.stringToElement(episode)) </h1> </View>
};
```

Am I supposed to pass list(episode) somewhere?

UPDATE 2: This code works as far as JSX thanks to @glennsl

```

let make = (_) => {
  ...component,
  render: (_self) =>
    <View>
      <Hello message="Hello from home component" />
      /* <Greeting name="Tony" /> */
      <FetchEpisodes>
        (
          (response) => {
            let episodeItems =
              response##data##allEpisodes
              |> Array.map((episode) => <Episode key=episode##id episode=episode##episode />);
            <div>
              <h1> (ReasonReact.stringToElement("Episodes!")) </h1>
              (ReasonReact.arrayToElement(episodeItems))
            </div>
          }
        )
      </FetchEpisodes>
    </View>
};
```

Solution

  • This should work, I think:

    type episode = {. "id": string, "title": string, "episode": string};
    type data = {. "allEpisodes": array(episode)};
    
    ...
    
    (response) => {
      let episodeItems =
        response##data##allEpisodes
        |> Array.map((episode) =>
           <Episode key=episode##id
                    episode=episode##episode />);
    
      <div>
        <h1> (ReasonReact.stringToElement("Episodes!")) </h1>
        (ReasonReact.arrayToElement(episodeItems))
      </div>
    }
    

    Let me know if it doesn't, or if any of this confuses you I'll happily explain.

    Edit: You've also typed data##allEpisodes as list(episode) when it's actually array(episode). Updated the code block above. A list is not the same as an array, the former is a linked list type while the latter is equivalent to a JavaScript array.

    Edit 2: Fixed JSX