I'm trying to filter particular Eateries based on foodType
which is passed as a string eg("Chicken", "Pizza" etc).
I want to be able to do it onClick
in my React component .
I've tried wrapping in an <ApolloPriver>
wrapper to do a query but not had much luck.
FoodType.tsx
export const FoodTypes: React.SFC = () => {
return (
<div className="food-types">
<ul className="food-type-list">
<li className="food-type-item" onClick={async () => {
const { data } = await client.query({
query: FOODTYPE_QUERY,
variables: { foodType: "Pizza" }
})}}>Pizza</li>
<li className="food-type-item" onClick={}>Chicken</li>
<li className="food-type-item" onClick={}>Indian</li>
<li className="food-type-item" onClick={}>Chinese</li>
<li className="food-type-item" onClick={}>English</li>
<li className="food-type-item" onClick={}>Fish & Chips</li>
<li className="food-type-item" onClick={}>Kebab</li>
<li className="food-type-item" onClick={}>Curry</li>
<li className="food-type-item" onClick={}>Caribbean</li>
</ul>
)}
The GQL query I want to pass
const FOODTYPE_QUERY = gql`
query foodTypeQuery($foodType: String!) {
getFoodType(foodType: $foodType) {
id
name
address
foodType
}
}
`;
How I'm currently showing all the eateries in FoodTypes.tsx
. This is where I want the results to go onClick
of the buttons above.
<div className={"EateryWrapper"}>
<ApolloProvider client={client}>
<Query query={EATERY_QUERY}>
{({ loading, data }: any) => {
if (loading) return "Loading...";
const { eateries } = data;
return eateries.map((eatery: any) => (
<EateryItem
key={eatery.id}
id={eatery.id}
name={eatery.name}
address={eatery.address}
foodType={eatery.foodType}
/>
));
}}
</Query>
</ApolloProvider>
</div>
The whole FoodTypes.tsx
import React from "react";
import "./FoodTypes.scss";
import { ApolloProvider, Query } from "react-apollo";
import { gql } from "apollo-boost";
import { client } from "../..";
import { EateryItem } from "../Eatery/EateryItem";
const EATERY_QUERY = gql`
{
eateries {
id
name
address
foodType
}
}
`;
const FOODTYPE_QUERY = gql`
query foodTypeQuery($foodType: String!) {
getFoodType(foodType: $foodType) {
id
name
address
foodType
}
}
`;
export const FoodTypes: React.SFC = () => {
return (
<div className="food-types">
<ul className="food-type-list">
<li className="food-type-item" onClick={async () => {
const { data } = await client.query({
query: FOODTYPE_QUERY,
variables: { foodType: "Pizza" }
})
console.log(data)}
}>Pizza</li>
<li className="food-type-item">Chicken</li>
<li className="food-type-item">Indian</li>
<li className="food-type-item">Chinese</li>
<li className="food-type-item">English</li>
<li className="food-type-item">Fish & Chips</li>
<li className="food-type-item">Kebab</li>
<li className="food-type-item">Curry</li>
<li className="food-type-item">Caribbean</li>
</ul>
<div className={"EateryWrapper"}>
<ApolloProvider client={client}>
<Query query={EATERY_QUERY}>
{({ loading, data }: any) => {
if (loading) return "Loading...";
const { eateries } = data;
return eateries.map((eatery: any) => (
<EateryItem
key={eatery.id}
id={eatery.id}
name={eatery.name}
address={eatery.address}
foodType={eatery.foodType}
/>
));
}}
</Query>
</ApolloProvider>
</div>
</div>
);
};
export default FoodTypes;
Updated FoodTypes.tsx
import React, { Component, useState } from "react";
import "./FoodTypes.scss";
import { ApolloProvider, Query } from "react-apollo";
import { gql } from "apollo-boost";
import { client } from "../..";
import { EateryItem } from "../Eatery/EateryItem";
const EATERY_QUERY = gql`
{
eateries {
id
name
address
foodType
}
}
`;
const FOODTYPE_QUERY = gql`
query foodTypeQuery($foodType: String!) {
getFoodType(foodType: $foodType) {
id
name
address
foodType
}
}
`;
type foodTypeFilterProps = {
foodTypeName: String
}
export const FoodTypes: React.SFC = () => {
return (
<div className="food-types">
<ul className="food-type-list">
<FoodTypeFilter foodTypeName={'Italian'}/>
<FoodTypeFilter foodTypeName={'Pizza'}/>
<FoodTypeFilter foodTypeName={'Chicken'}/>
<FoodTypeFilter foodTypeName={'Indian'}/>
<FoodTypeFilter foodTypeName={'Chinese'}/>
<FoodTypeFilter foodTypeName={'English'}/>
<FoodTypeFilter foodTypeName={'Fish & Chips'}/>
<FoodTypeFilter foodTypeName={'Kebab'}/>
<FoodTypeFilter foodTypeName={'Curry'}/>
<FoodTypeFilter foodTypeName={'Caribbean'}/>
</ul>
<div className={"EateryWrapper"}>
<ApolloProvider client={client}>
<Query query={EATERY_QUERY}>
{({ loading, data }: any) => {
if (loading) return "Loading...";
const { eateries } = data;
return eateries.map((eatery: any) => (
<EateryItem
key={eatery.id}
id={eatery.id}
name={eatery.name}
address={eatery.address}
foodType={eatery.foodType}
/>
));
}}
</Query>
</ApolloProvider>
</div>
</div>
);
};
const FoodTypeFilter: React.FunctionComponent<foodTypeFilterProps> = props => {
const [foodType, setFoodType] = useState(props.foodTypeName);
return(
<li className="food-type-item" onClick={async () => {
const { data } = await client.query({
query: FOODTYPE_QUERY,
variables: { foodType: props.foodTypeName }
})
setFoodType(foodType);
}}>{foodType}
</li>
)
}
export default FoodTypes;
What would the best approach be to get the above elements to use the GQL query above onClick?
Firstly, I would recommend you change your FoodTypes
component to a React component so that you are able to store the data returned from your graphql query in state
export class classFoodTypes extends React.Component
Now, in your classFoodTypes
component, you can call setState
after fetching your data:
<li className="food-type-item" onClick={async () => {
const { data } = await client.query({
query: FOODTYPE_QUERY,
variables: { foodType: "Pizza" }
})}
this.setState({eateries: data})}>Pizza</li>
From there, you can display your data from state
:
<EateryItem
key={this.state.eateries.id}
id={this.state.eateries.id}
name={this.state.eateries.name}
address={this.state.eateries.address}
foodType={this.state.eateries.foodType}
/>
I'm not going to finish implementing the rest of your component so you can practice the implementation, but this pattern should help lead you in the right direction. Let me know if you get stuck along the way.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.