2

I'm currently trying to take a GraphQL query and using Apollo, display the result on my React Native app.

Here is the relevant code in App.js:

import {LoginScreen} from './src/Screens'
import ApolloClient from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';

const myLink = new HttpLink({
  uri: 'http://localhost:5000/graphql',
});

const client = new ApolloClient({
  link: myLink,
  cache: new InMemoryCache()
});

export default class App extends React.Component{
  render() {
    return(
      <ApolloProvider client={client}>
        <LoginScreen/>
      </ApolloProvider>
    )}
}'

And here is the relevant code in LoginScreen.js

function ShowUser({data: { loading, otsUserByUserId }}) {
    if (loading) {
      return <Text>Loading</Text>;
    } else {
        console.log("Ots user is " + otsUserByUserId)
        console.log("Data: " + data)
      return (
        <View>
            {otsUserByUserId.map(user =>
                <Text>The name of user is {user.firstName} {user.lastName}.</Text>
            )}
        </View>
      );
    }
  }

export default graphql(gql`
    query otsUser{
        otsUserByUserId(userId:1) {
            firstName
            lastName
        }
    }
`)(ShowUser)

My query works in GraphiQL as you can see: Graphiql Query

And just to show that I'm using the correct endpoint for my link: Start GraphQL Server

When running this, in my debugger, I see Chrome Developer Tools Response

This shows that data is undefined and it's a networking error. So I must be doing something wrong on my setup on the front end. In some way, I am not using Apollo correctly. It seems pretty obvious that the error is in my App.js in how I define client, but I haven't been able to get anything to work for a while now, and it's driving me nuts. I can't find any SO posts on this.

I've gone through the Apollo docs multiple times and have been trying to just get something to work for a few days now. Any help is much appreciated. Thank you for your time.

Brandon Willis
  • 145
  • 2
  • 15

1 Answers1

2

The problem is localhost only means something to your computer, but means nothing to your react native app since the server is not running on it. Try changing localhost to your computer's IP address. That should hook you up.

const myLink = new HttpLink({
  uri: 'http://{COMPUTER_IP_ADDRESS_HERE}:5000/graphql',
});

Update: 11/21

Below is to deal with your additional questions left in the comments.

  1. If you have a better idea, please do not hesitate to tell me and I will try it.
  2. Why can't I just do console.log(props.data)?

1. How I've done it

Here's a copy/paste of a working login page from one of my demo/toy apps. I know it works. It basically does the same thing you're attempting with a couple nice additions (e.g. managed form state, passing vars to the HOC, localstorage caching). You should be able to get what you need from it and adapt it to your use case easily.

// LoginScreen.js
import React from 'react';
import { gql, graphql } from 'react-apollo';
import { Button, Input } from 'rebass';

import { AUTH_TOKEN_KEY } from '../config';

class Login extends React.Component {
  state = {
    form: {
      email: '',
      password: ''
    },
    submitting: false
  };

  handleSubmit = evt => {
    evt.preventDefault();
    this.setState({
      submitting: true
    });

    const { email, password } = this.state.form;
    this.props
      .signinUser({ variables: { email, password } })
      .then(res => {
        window.localStorage.setItem(AUTH_TOKEN_KEY, res.data.signinUser.token);
        window.location = '/';
      })
      .catch(err => console.error(err));
  };

  handleChange = evt => {
    const { name, value } = evt.target;

    this.setState({
      form: {
        ...this.state.form,
        [name]: value
      }
    });
  };

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <h1>Login</h1>
        <Input
          type="text"
          name="email"
          label="Email"
          value={this.state.form.email}
          // baseRef={ref => ref.focus()}
          onChange={this.handleChange}
        />
        <Input
          type="password"
          name="password"
          label="Password"
          value={this.state.form.password}
          onChange={this.handleChange}
        />
        <Button>Login</Button>
      </form>
    );
  }
}

const signinUser = gql`
  mutation($email: String!, $password: String!) {
    signinUser(email: { email: $email, password: $password }) {
      token
    }
  }
`;

export default graphql(signinUser, { name: 'signinUser' })(Login);

2. console.log(props.data)

You should be able to log this. Not sure what you're seeing, but I'm assuming it's something like [Object] from your description. If that's true, try this console.log('props.data %j', props.data) which will convert props.data to json if possible. You can also try console.log({props}) to see the entire props tree. If neither works the way you want, then you probably have something else going on here.

If you have more questions, you should probably open new stack overflow questions. These are really meant to just be one-to-one kinds of things, one question, one answer.

Chris Geirman
  • 9,474
  • 5
  • 37
  • 70
  • I think we're one step closer, but I still get an error that "data" is undefined. Could this still be a network issue? – Brandon Willis Nov 21 '17 at 18:30
  • cool, I think you just need to access data on the props, so `props.data` – Chris Geirman Nov 21 '17 at 20:31
  • wait, nevermind...I see you're destructuring data off of props. Hmmm, I'm not sure. Try inspecting your props in react-tools and see if you can figure it out. I don't see anything obvious – Chris Geirman Nov 21 '17 at 20:35
  • Honestly, ANY way to make this work, I will do. If you have a better idea, please do not hesitate to tell me and I will try it. There is hardly any front end code written right now, so it'd be very easy to replace. – Brandon Willis Nov 21 '17 at 21:03
  • I also have the following code from when I was trying to destructure the data into an object. https://pastebin.com/6skMwP39 – Brandon Willis Nov 21 '17 at 21:17
  • Also, why can't I just do console.log(props.data)? I get like an object array or something. – Brandon Willis Nov 21 '17 at 21:46