I am trying to pose a react ponent with the following queries, but the query getMe
is always an object and then I get TypeError: this.props.getMe is not a function
. If I change it to a mutation then it all works. If I use the query in the graphiql web interface it works too. I am running out of ideas. Anyone spot something obvious.
The problematic part
const getMe = gql`
query
{
viewer
{
_id
name
email
gender
birthday
picture
role
facebookId
facebookEmail
token
}
}
`
export default pose(
graphql(login, {name : 'authorizeUser'}),
graphql(logout, {name : 'deauthorizeUser'}),
graphql(getMe, {name : 'getMe'}),
)(App);
Here is the whole file
Just in case it helps
import React from 'react';
import { Button } from 'reactstrap'
import FacebookLogin from 'react-facebook-login';
import { pose, graphql } from 'react-apollo';
import gql from 'graphql-tag';
import './App.css';
class App extends React.Component
{
constructor(props)
{
super(props);
this.state = { loggedin: !!window.localStorage.getItem('token') };
}
login(res)
{
this.props.authorizeUser({
variables: { accessToken: res.accessToken }
})
.then((data) => {
console.log('got token', data.data.authorizeUser.token);
window.localStorage.setItem('token', data.data.authorizeUser.token)
this.setState({ loggedin: true, user: data.data.authorizeUser })
console.log(this.state)
}).catch((error) => {
console.log('there was an error sending the query', error);
window.localStorage.removeItem('token')
this.setState({ loggedin: true })
});
}
logout()
{
const token = window.localStorage.getItem('token')
if (!token) {
window.localStorage.removeItem('token')
this.setState({ loggedin: false })
return
}
this.props.deauthorizeUser({
variables:{ token }
})
.then((data) => {
console.log('destroyed token', data);
window.localStorage.removeItem('token')
this.setState({ loggedin: false })
});
}
me()
{
const token = window.localStorage.getItem('token')
console.log(this.props)
this.props.getMe({
variables:{ token }
})
.then((data) => {
this.setState({ loggedin: true, user: data.data.authorizeUser })
})
}
ponentDidMount()
{
if (this.state.loggedin)
{
this.me()
}
}
render()
{
return (
<div className="App">
<br/>
{ !this.state.loggedin &&
<FacebookLogin
appId="298798940239793"
autoLoad={false}
fields="name,email,picture"
callback={ this.login.bind(this) } />
}
{ this.state.loggedin &&
<Button color="primary" onClick={ this.logout.bind(this) }>Logout</Button>
}
{ this.state.loggedin && this.state.user &&
<div>
<img src={`/${this.state.user.facebookId}/picture?type=large`} alt="profile pic"/>
<div>{this.state.user.name}</div>
<div>{this.state.user.email}</div>
<div>{this.state.user.gender}</div>
<div>{this.state.user.birthday}</div>
<div>{this.state.user.role}</div>
</div>
}
</div>
)
}
}
const login = gql`
mutation authorizeUser($accessToken: String!)
{
authorizeUser(accessToken: $accessToken)
{
_id
name
email
gender
birthday
picture
role
facebookId
facebookEmail
token
}
}
`
const logout = gql`
mutation deauthorizeUser($token: String!)
{
deauthorizeUser(token: $token)
{
success
}
}
`
const getMe = gql`
query
{
viewer
{
_id
name
email
gender
birthday
picture
role
facebookId
facebookEmail
token
}
}
`
export default pose(
graphql(login, {name : 'authorizeUser'}),
graphql(logout, {name : 'deauthorizeUser'}),
graphql(getMe, {name : 'getMe'}),
)(App);
You can ignore the poor quality of this code, I am just playing around
I am trying to pose a react ponent with the following queries, but the query getMe
is always an object and then I get TypeError: this.props.getMe is not a function
. If I change it to a mutation then it all works. If I use the query in the graphiql web interface it works too. I am running out of ideas. Anyone spot something obvious.
The problematic part
const getMe = gql`
query
{
viewer
{
_id
name
email
gender
birthday
picture
role
facebookId
facebookEmail
token
}
}
`
export default pose(
graphql(login, {name : 'authorizeUser'}),
graphql(logout, {name : 'deauthorizeUser'}),
graphql(getMe, {name : 'getMe'}),
)(App);
Here is the whole file
Just in case it helps
import React from 'react';
import { Button } from 'reactstrap'
import FacebookLogin from 'react-facebook-login';
import { pose, graphql } from 'react-apollo';
import gql from 'graphql-tag';
import './App.css';
class App extends React.Component
{
constructor(props)
{
super(props);
this.state = { loggedin: !!window.localStorage.getItem('token') };
}
login(res)
{
this.props.authorizeUser({
variables: { accessToken: res.accessToken }
})
.then((data) => {
console.log('got token', data.data.authorizeUser.token);
window.localStorage.setItem('token', data.data.authorizeUser.token)
this.setState({ loggedin: true, user: data.data.authorizeUser })
console.log(this.state)
}).catch((error) => {
console.log('there was an error sending the query', error);
window.localStorage.removeItem('token')
this.setState({ loggedin: true })
});
}
logout()
{
const token = window.localStorage.getItem('token')
if (!token) {
window.localStorage.removeItem('token')
this.setState({ loggedin: false })
return
}
this.props.deauthorizeUser({
variables:{ token }
})
.then((data) => {
console.log('destroyed token', data);
window.localStorage.removeItem('token')
this.setState({ loggedin: false })
});
}
me()
{
const token = window.localStorage.getItem('token')
console.log(this.props)
this.props.getMe({
variables:{ token }
})
.then((data) => {
this.setState({ loggedin: true, user: data.data.authorizeUser })
})
}
ponentDidMount()
{
if (this.state.loggedin)
{
this.me()
}
}
render()
{
return (
<div className="App">
<br/>
{ !this.state.loggedin &&
<FacebookLogin
appId="298798940239793"
autoLoad={false}
fields="name,email,picture"
callback={ this.login.bind(this) } />
}
{ this.state.loggedin &&
<Button color="primary" onClick={ this.logout.bind(this) }>Logout</Button>
}
{ this.state.loggedin && this.state.user &&
<div>
<img src={`http://graph.facebook./${this.state.user.facebookId}/picture?type=large`} alt="profile pic"/>
<div>{this.state.user.name}</div>
<div>{this.state.user.email}</div>
<div>{this.state.user.gender}</div>
<div>{this.state.user.birthday}</div>
<div>{this.state.user.role}</div>
</div>
}
</div>
)
}
}
const login = gql`
mutation authorizeUser($accessToken: String!)
{
authorizeUser(accessToken: $accessToken)
{
_id
name
email
gender
birthday
picture
role
facebookId
facebookEmail
token
}
}
`
const logout = gql`
mutation deauthorizeUser($token: String!)
{
deauthorizeUser(token: $token)
{
success
}
}
`
const getMe = gql`
query
{
viewer
{
_id
name
email
gender
birthday
picture
role
facebookId
facebookEmail
token
}
}
`
export default pose(
graphql(login, {name : 'authorizeUser'}),
graphql(logout, {name : 'deauthorizeUser'}),
graphql(getMe, {name : 'getMe'}),
)(App);
Share Improve this question edited Mar 27, 2019 at 8:42 Marco Daniel 5,7755 gold badges30 silver badges37 bronze badges asked Jan 18, 2018 at 18:27 BrenwellBrenwell 73113 silver badges27 bronze badges 3You can ignore the poor quality of this code, I am just playing around
- Did you ever find a solution for this? I'm facing exactly the same problem! – Chuckatron Commented Mar 29, 2018 at 9:49
- yes I did actually let me look – Brenwell Commented Mar 29, 2018 at 10:54
- @AndrewIsherwood Please check my answer and let me know if it worked – Brenwell Commented Mar 29, 2018 at 11:03
3 Answers
Reset to default 3Finally found solution here
The points is
import { withApollo } from 'react-apollo'
class LoginForm extends Component {
// query by client.query
const queryUserResult = await this.props.client.query({
query: QUERY_USER,
variables: { name: value });
}
const MUTATION = gql`
mutation {
// some mutation logic
}
`
const QUERY = gql`
query {
// some query logic
}
`
export default pose(
withApollo,
graphql(MUTATION , { name: 'mutation' })
)(LoginForm))
I see your main problem is with the syntax of the query. Below I give some examples of different queries using the gql
from graphql-tag
which you have used.
Using these bits and pieces could hopefully help
Example 1:
const SIGNUP_MUTATION = gql`
mutation SignupMutation($email: String!, $password: String!, $name: String!) {
signup(email: $email, password: $password, name: $name) {
token
}
}`
signup
is the name of the resolver function in the backend
Example 2:
const FEED_QUERY = gql`
query FeedQuery($first: Int, $skip: Int, $orderBy: LinkOrderByInput) {
feed(first: $first, skip: $skip, orderBy: $orderBy) {
links {
id
createdAt
url
description
postedBy {
id
name
}
votes {
id
user {
id
}
}
}
count
}
}`
Similarly here feed is the name of the resolver function int the backend.
Also you could try
@pose(graphql(queryname , {name: 'logindata'}), graphql(...,{...}),...)
at the top of your App class. This is how I have used recently.
I couldn't quite remember what I had done, but since I was asked about my solution I thought I would post the change I made.
// call it like this
this.viewer()
...
const me = gql`
query user
{
viewer
{
_id
name
email
gender
birthday
picture
role
facebookId
facebookEmail
token
}
}
`
export default pose(
graphql(login, {name : 'authorizeUser'}),
graphql(logout, {name : 'deauthorizeUser'}),
graphql(me),
)(App);