我正在使用Graphql和React进行项目,但是我有一个问题,查询返回值undefined
。我正在将值传递给变量,但是却给出了...
我的查询返回undefined
(带有React)(FilterResult):
import React, { Fragment } from 'react';
import { Query } from 'react-apollo';
import { InlineLoading } from 'carbon-components-react';
import ReactSVG from 'react-svg';
import Module from '../../components/Module/Module';
import ViewMore from '../../components/ViewMore/ViewMore';
import SearchContext from './context';
import { GET_POSITIONS_BY_FILTER } from './queries';
import Position from '../../components/Position/Position';
import { HorizontalSeparator } from '../dashboard/styled';
import emptySearchIcon from './empty-search.svg';
import { EmptySearchContainer, ViewMoreContainer } from './styled.js';
const FilterResult = () => (
<SearchContext.Consumer>
{context => (
<Query query={GET_POSITIONS_BY_FILTER} variables={{ filters: context.filters, offset: 0 }}>
{({ data, loading, fetchMore }) => {
if (loading) return <InlineLoading description="Loading..." />;
let filterResult;
{
data.filter.positions.length
? (filterResult = (
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
{data.filter.positions.map((position, index, arr) => (
<Fragment key={position.id}>
<Position position={position} />
{index + 1 !== arr.length ? <HorizontalSeparator /> : null}
</Fragment>
))}
</div>
))
: (filterResult = (
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
<EmptySearchContainer>
<ReactSVG path={emptySearchIcon} />
<h5>No results found</h5>
<h6>Try different filters or keywords and search it again</h6>
</EmptySearchContainer>
</div>
));
}
return (
<React.Fragment>
<Module title="All Results" description={` - ${data.filter.positions.length} job opportunities`}>
{filterResult}
</Module>
<ViewMoreContainer>
<a onClick={() => fetchMore({
variables: {
offset: data.filter.positions.length
},
updateQuery: (prev, { fetchMoreResult }) => {
if (!fetchMoreResult) return prev;
return {
...prev,
filter: {
...prev.filter,
positions: [
...prev.filter.positions,
...fetchMoreResult.filter.positions
]
}
};
}
})}>View More</a>
</ViewMoreContainer>
</React.Fragment>
);
}}
</Query>
)}
</SearchContext.Consumer>
);
export default FilterResult;
变量undefined
是data
。
我的typedef:
const Position = `
input InputFilters {
status: [String!]
country: String
city: String
band: Int
role: String
businessUnit: String
domain: String,
subDomain: String,
keywords: String,
}
type PositionFilters {
countries: [String!]
cities(country: String!): [String!]
roles: [String!]
businessUnit: [String!]
domains: [String!]
subDomains(domain: String!): [String!]
positions(filters: InputFilters!, offset: Int): [Position!]
}
type Position {
id: ID!
type: PositionType!
role: String!
responsibilities: String
skills: String
country: String!
quantity: Int
expirationDate: Timestamp!
availableDate: Timestamp!
band: Int!
functionalManager: String!
bluepagesManager: String!
managementContact: String!
gomNumber: String
location: String!
businessUnit: String!
domain: String!
subDomain: String!
viewCount: Int
favoriteCount: Int
owner_id: String!
closed: Boolean
closedType: ClosedType
owner: User!
favorites: [User!]!
views: [User!]!
created_at: Timestamp!
updated_at: Timestamp!
}
`;
module.exports = Position;
我的resolver
:
const Position = require('./position.model');
const User = require('../User/user.model');
const Favorite = require('../Favorite/favorite.model');
const View = require('../View/view.model');
const { AuthenticationError } = require('apollo-server-express');
module.exports = {
Query: {
positions() {
return Position.all();
},
position(_, args) {
return Position.findById(args.id);
},
},
Position: {
owner(root) {
return User.findById(root.owner_id);
},
favorites(root) {
return Favorite.getPositionFavorites(root.id);
},
views(root) {
return View.getPositionViews(root.id);
},
},
PositionFilters: {
countries() {
return Position.getAllCountries();
},
cities(_, args) {
return Position.getCountryCities(args.country);
},
roles() {
return Position.getAllRoles();
},
businessUnit() {
return Position.getAllBusinessUnit();
},
domains() {
return Position.getAllDomains();
},
subDomains(_, args) {
return Position.getSubDomains(args.domain);
},
positions(_, { filters, offset }) {
return Position.getByFilters(filters, offset);
},
},
Mutation: {
async closePosition(_, args) {
return Position.closePosition(args.positionID, args.closedType);
},
async createPosition(_, args, context) {
if (context.user) {
const position = { ...args.input, owner_id: context.user.id };
const response = await Position.insert(position);
return response[0];
}
throw new AuthenticationError('You need to be logged');
},
async updatePosition(_, args, context) {
// TODO: Verify if user which is mutating the position is actually the owner of it
if (context.user) {
const response = await Position.update(args.input);
return response[0];
}
throw new AuthenticationError('You need to be logged');
},
},
};
我不知道结构如何,因为我现在收到了该项目,并且对GraphQL不太了解。
第一行API Context
中也有FilterResult
。
Api Context
:
import React from 'react';
const SearchContext = React.createContext();
export default SearchContext;
带有ApolloProvider
的App.js:
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { ApolloProvider } from 'react-apollo';
import client from './graphql/client';
import PrivateRoute from './components/RouteWrapper/PrivateRoute';
import Dashboard from './pages/dashboard/dashboard';
import Search from './pages/search/Search';
import Login from './pages/login/login';
import MutatePosition, { Edit, New, PositionFetcher, ManagerFetcher } from './pages/mutatePosition/index';
import Position from './pages/vacancy/Vacancy';
import View from './pages/vacancy/View';
import Error404 from './pages/404/404';
import 'carbon-components/css/carbon-components.min.css';
import './assets/CSS/style';
import './assets/CSS/style.css';
const App = () => (
<ApolloProvider client={client}>
<Router>
<div>
<Route exact path="/" component={Login} />
<Route exact path="/login" component={Login} />
<PrivateRoute exact path="/search" component={Search} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<Switch>
<PrivateRoute
exact
path="/vacancy/new"
render={() => <MutatePosition>{props => <New {...props} />}</MutatePosition>}
/>
<PrivateRoute
exact
path="/vacancy/:id/edit"
render={props => (
<PositionFetcher id={props.match.params.id}>
{position => <MutatePosition position={position}>{props => <Edit {...props} />}</MutatePosition>}
</PositionFetcher>
)}
/>
<PrivateRoute
exact
path="/vacancy/:id"
render={props => <View {...props}>{props => <Position {...props} />}</View>}
/>
</Switch>
</div>
</Router>
</ApolloProvider>
);
export default App;