最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Apollo-react compose query is not a function - Stack Overflow

programmeradmin3浏览0评论

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);

You can ignore the poor quality of this code, I am just playing around

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 3
  • 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
Add a ment  | 

3 Answers 3

Reset to default 3

Finally 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);
发布评论

评论列表(0)

  1. 暂无评论