Неправильный статус 500 в запросах Apollo GraphQL («Переменная X необходимого типа \« String! \ »Не была предоставлена».) - PullRequest
0 голосов
/ 19 января 2020

Я получаю сетевую ошибку только в некоторых случаях, когда я вызываю lazyQuery в своем проекте React с Apollo и GraphQL. В моем приложении я могу успешно вернуть результаты поиска, содержащие различные напитки. Они сопоставлены с их собственными кнопками. При нажатии на одну из этих кнопок запускается функция, которая запрашивает данные об этом конкретном c напитке.

В большинстве случаев он работает нормально, но иногда я получаю сообщение об ошибке статуса 500, говоря, что переменная cocktailName строки типа не указывается. Когда я несколько раз пытался заказать одни и те же напитки, я иногда получал хороший ответ, а иногда нет. Когда я пытаюсь отладить функцию, отправляющую запрос, она, кажется, получает переменную каждый раз, и мне не удается обработать sh приложение, когда у меня есть отладочные точки останова в этой функции. Буду очень признателен за любую помощь в этом!

Основной компонент для напитков:

import React from 'react';
import { useStoreState, useStoreActions } from 'easy-peasy';
import { useQuery, useLazyQuery } from '@apollo/react-hooks';
import { RANDOM_COCKTAIL_QUERY, ONE_COCKTAIL_BY_NAME_QUERY } from './Queries';
import LoadingSpinner from './LoadingSpinner';
import CocktailSearchFieldAlt from './CocktailSearchFieldAlt';
import { cocktailIngredientList, cocktailMeasureList } from './ingredientLists';

// Imported ingredient and measure lists represent names of keys in objects

export default function Cocktails() {
    const dataType = useStoreState((state) => state.cocktailDataType);
    const changeDataType = useStoreActions((actions) => actions.changeCocktailDataType);
    const dataSet = useStoreState((state) => state.cocktailDataSet);
    const changeDataSet = useStoreActions((actions) => actions.changeCocktailDataSet);

    const randomizeClick = () => {
        if (dataType !== 'randomCocktail') {
            changeDataType('randomCocktail');
            changeDataSet('data');
        }
        refetch();
    };

    const specifikLookup = (drinkName) => {
        if (dataType === 'randomCocktail') {
            changeDataSet('specificData');
            changeDataType('oneCocktailByName');
        }
        getDrink({ variables: { cocktailName: drinkName } });
    };

    const { loading, error, data, refetch } = useQuery(RANDOM_COCKTAIL_QUERY);
    const [
        getDrink,
        { data: specificData, loading: loadingSpecific, error: errorSpecific }
    ] = useLazyQuery(ONE_COCKTAIL_BY_NAME_QUERY);

    if (loading || loadingSpecific) return <LoadingSpinner />;
    if (error) return `Error! ${error}`;
    if (errorSpecific) return `Error! ${errorSpecific}`;

    return (
        <section id="cocktail">
            <h2 className="mainHeader mt-5 mb-4 scrollTrick">Cocktail</h2>
            <div className="card card-body mb-3">
                <div className="row">
                    <div className="col-md-9">
                        <h4>{eval(dataSet)[dataType].strDrink}</h4>
                        <p>
                            {eval(dataSet)[dataType].strAlcoholic}
                            <br />
                            Best served in: {eval(dataSet)[dataType].strGlass}
                        </p>

                        <h6>Recipee</h6>
                        <div className="row">
                            <div className="col-md-4">
                                <ul>
                                    {eval(dataSet) &&
                                        cocktailIngredientList.map(
                                            (x, i) =>
                                                eval(dataSet)[dataType][x] && (
                                                    <li key={i}>{eval(dataSet)[dataType][x]}</li>
                                                )
                                        )}
                                </ul>
                            </div>
                            <div className="col-md-3">
                                <ul>
                                    {data &&
                                        cocktailMeasureList.map(
                                            (x) => eval(dataSet)[dataType][x] && <li>{eval(dataSet)[dataType][x]}</li>
                                        )}
                                </ul>
                            </div>
                        </div>
                        <h6>Instructions</h6>
                        <p>{eval(dataSet)[dataType].strInstructions}</p>
                    </div>
                    <div className="col-md-3">
                        <img src={eval(dataSet)[dataType].strDrinkThumb} alt="Cocktail" className="img-fluid mb-3" />
                        <button className="btn btn-primary btn-block" onClick={() => randomizeClick()}>
                            Randomize Cocktail
                        </button>
                    </div>
                </div>
                {/* <CocktailSearchField specificLookup={specifikLookup} /> */}
                <CocktailSearchFieldAlt specificLookup={specifikLookup} />
            </div>
        </section>
    );
}

Поиск компонента для напитков:

import React, { useState } from 'react';
import { useStoreState, useStoreActions } from 'easy-peasy';
import { useLazyQuery } from '@apollo/react-hooks';
import { MULTIPLE_COCKTAILS_BY_NAME_QUERY, MULTIPLE_COCKTAILS_BY_INGREDIENT_QUERY } from './Queries';
import LoadingSpinner from './LoadingSpinner';

export default function SearchField(props) {
    const [
        searchInput,
        setSearchInput
    ] = useState('');

    const drinkOptionValue = useStoreState((state) => state.drinkOptionValue);
    const changeDrinkOptionValue = useStoreActions((actions) => actions.changeDrinkOptionValue);

    const handleSubmit = (e) => {
        e.preventDefault();
        getDrinks({ variables: { cocktailName: searchInput } });
        getDrinksByIngredient({ variables: { ingredientName: searchInput } });
    };

    const [
        getDrinks,
        { loading, data }
    ] = useLazyQuery(MULTIPLE_COCKTAILS_BY_NAME_QUERY);

    const [
        getDrinksByIngredient,
        { loading: loadingByIngredient, data: dataByIngredient }
    ] = useLazyQuery(MULTIPLE_COCKTAILS_BY_INGREDIENT_QUERY);

    const lookupDrink = (e) => {
        console.log(e.target.value);

        changeDrinkOptionValue(e.target.value);
        props.specificLookup(e.target.value);
    };

    if (loading || loadingByIngredient) return <LoadingSpinner />;

    return (
        <div>
            <div className="row border-top mt-3 justify-content-center">
                <div className="mt-3">
                    <form className="form-inline my-2 my-lg-0" onSubmit={handleSubmit}>
                        <input
                            className="form-control mr-sm-1"
                            type="text"
                            placeholder="Search cocktail"
                            onChange={(e) => setSearchInput(e.target.value)}
                            value={searchInput}
                        />
                        <button className="btn btn-secondary my-2 my-sm-0 pl-3 pt-2 pb-2 pr-3" type="submit">
                            <i className="material-icons mt-2">search</i>
                        </button>
                    </form>
                </div>
            </div>
            {data &&
                (data.multipleCocktailsByName !== null ? (
                    <div className="container">
                        <div className="row">
                            <div className="col">
                                <h6 className="mt-3 mb-3 text-center">Search results: </h6>
                            </div>
                        </div>
                        <div className="row justify-content-center">
                            {dataByIngredient.multipleCocktailsByIngredient !== null &&
                                dataByIngredient.multipleCocktailsByIngredient.map((cocktailByIngredient) => {
                                    if (
                                        data.multipleCocktailsByName.some(
                                            (cocktail) => cocktail.strDrink === cocktailByIngredient.strDrink
                                        )
                                    ) {
                                        return;
                                    } else {
                                        data.multipleCocktailsByName.push(cocktailByIngredient);
                                    }
                                })}

                            {
                                (data.multipleCocktailsByName.sort(
                                    (a, b) => (a.strDrink > b.strDrink ? 1 : b.strDrink > a.strDrink ? -1 : 0)
                                ),
                                data.multipleCocktailsByName.map((cocktail, i) => (
                                    <button
                                        className="btn btn-outline-secondary p-1 menuButton btnAnimated mr-1 mb-1 border border-secondary"
                                        key={i}
                                        value={cocktail.strDrink}
                                        onClick={lookupDrink}
                                    >
                                        <img src={cocktail.strDrinkThumb} className="menuPicture" alt="cocktail" />
                                        {cocktail.strDrink}
                                    </button>
                                )))
                            }
                        </div>
                    </div>
                ) : dataByIngredient.multipleCocktailsByIngredient !== null ? (
                    <div className="container">
                        <div className="row">
                            <div className="col">
                                <h6 className="mt-3 mb-3 text-center">Search results: </h6>
                            </div>
                        </div>
                        <div className="row justify-content-center">
                            {dataByIngredient.multipleCocktailsByIngredient.map((cocktail, i) => (
                                <button
                                    className="btn btn-outline-secondary p-1 menuButton btnAnimated mr-1 mb-1 border border-secondary"
                                    key={i}
                                    value={cocktail.strDrink}
                                    onClick={lookupDrink}
                                >
                                    <img src={cocktail.strDrinkThumb} className="menuPicture" alt="cocktail" />
                                    {cocktail.strDrink}
                                </button>
                            ))}
                        </div>
                    </div>
                ) : (
                    <div className="row justify-content-center">
                        <p>No matching result</p>
                    </div>
                ))}
        </div>
    );
}

...