Реакция Apollo: Uncaught (в обещании) TypeError: Невозможно прочитать свойство 'refetch' из неопределенного - PullRequest
0 голосов
/ 05 марта 2020

У меня есть функция, которая имеет некоторую цепочку обещаний, но это не имеет значения.

Когда я запускаю определенную мутацию refetch, она дает мне Uncaught (in promise) TypeError: Cannot read property 'refetch' of undefined.

Странная часть в том, что если я уберу мутацию перед ней, она будет работать. Итак, вот код:

Promise.all(this.props.questionnaireData.map(({ kind, id }): Promise<any> => {
    const responses = this.props.formData[kind];
    return this.props.updateQuestionnaire(id, responses);
})).then(() => {
    this.props.finishAssessment(this.props.assessmentId)
        .then(() => {
            track('Assessment -- Finished', {
                'Assessment Kind' : this.props.assessmentKind,
                'Assessment Id'   : this.props.assessmentId,
            });
            if (this.props.assessmentKind === 'INITIAL_ASSESSMENT') {
                this.props.getCompletedInitialAssessment.refetch().then(() => {
                    Router.replace(routes.LoadingAssessmentResults.to, routes.LoadingAssessmentResults.as);
                });

                this.submitEmailNotifications();
            } else if(this.props.assessmentKind === 'GOAL_CHECK_IN') {
                Router.replace(routes.MemberProgressDashboard.to, routes.MemberProgressDashboard.as);
            } else {
                Router.replace(routes.MemberDashboard.to, routes.MemberDashboard.as);
            }
        });
});

Ошибка происходит в this.props.getCompletedInitialAssessment.refetch(), и я не знаю почему. Тем не менее, когда я удаляю this.props.finishAssessment(this.props.assessmentId), только тогда будет работать повторное получение.

В основном:

Promise.all(this.props.questionnaireData.map(({ kind, id }): Promise<any> => {
    const responses = this.props.formData[kind];
    return this.props.updateQuestionnaire(id, responses);
})).then(() => {
        track('Assessment -- Finished', {
            'Assessment Kind' : this.props.assessmentKind,
            'Assessment Id'   : this.props.assessmentId,
        });
        if (this.props.assessmentKind === 'INITIAL_ASSESSMENT') {
            this.props.getCompletedInitialAssessment.refetch().then(() => {
            Router.replace(routes.LoadingAssessmentResults.to, routes.LoadingAssessmentResults.as);
            });

            this.submitEmailNotifications();
        } else if(this.props.assessmentKind === 'GOAL_CHECK_IN') {
            Router.replace(routes.MemberProgressDashboard.to, routes.MemberProgressDashboard.as);
        } else {
            Router.replace(routes.MemberDashboard.to, routes.MemberDashboard.as);
        }
});

сделает работу повторного поиска. В противном случае он жалуется, что не знает, что такое refetch.

Для Аполлона я использую graphql HO C, и это выглядит так:

graphql(getCompletedInitialAssessment, {
    name    : 'getCompletedInitialAssessment',
    options : { variables: { status: ['Finished'], limit: 1 } },
}),
graphql(updateQuestionnaire, {
    props: ({ mutate }) => ({
        updateQuestionnaire: (id, responses) => {
            let normalized = {};

                for (let res in responses) {
                    let num = +responses[res];
                    // If the value is a stringified numuber, turn it into a num
                    // otherwise, keep it a string.
                    normalized[res] = Number.isNaN(num) ? responses[res] : num;
                }

                const input = {
                    id,
                    patch: { responses: JSON.stringify(normalized) },
                };

                return mutate({
                    variables: { input },
                });
            },
        }),
    }),
graphql(finishAssessment, {
    props: ({ mutate }) => ({
        finishAssessment: (id) => {
            const input = { id };

            return mutate({
                variables      : { input },
                refetchQueries : ['getMemberInfo'],
            });
        },
    }),
}),

Что я Я пытался даже переписать это, чтобы использовать async / await, но проблема все еще возникает:

try {
    await Promise.all(this.props.questionnaireData.map(({ kind, id }): Promise<any> => {
        const responses = this.props.formData[kind];
        return this.props.updateQuestionnaire(id, responses);
    }));
    const finishAssessmentRes = await this.props.finishAssessment(this.props.assessmentId);
    console.log(finishAssessmentRes)

    if (this.props.assessmentKind === 'INITIAL_ASSESSMENT') {
        const res = await this.props.getCompletedInitialAssessment.refetch();
        console.log(res);
        this.submitEmailNotifications();
        Router.replace(routes.LoadingAssessmentResults.to, routes.LoadingAssessmentResults.as);
    } else if(this.props.assessmentKind === 'GOAL_CHECK_IN') {
        Router.replace(routes.MemberProgressDashboard.to, routes.MemberProgressDashboard.as);
    } else {
        Router.replace(routes.MemberDashboard.to, routes.MemberDashboard.as);
    }
} catch (error) {
    console.error(error);
}

Я, честно говоря, не знаю, что происходит или почему не работает refetch. Поможет ли рефакторинг в хуки? У кого-нибудь есть идеи?

1 Ответ

0 голосов
/ 05 марта 2020

С документы

Свойство config.props позволяет вам определить функцию карты, которая принимает реквизиты ..., добавленные функцией graphql() (props.data для запросов и props.mutate для мутаций) и позволяет вычислять новый реквизит ... объект , который будет предоставлен компоненту, который graphql() упаковывает .

Для доступа реквизиты, которые не добавляются функцией graphql(), используйте ключевое слово ownProps.

Используя функцию props, вы сообщаете HO C, который пропускает вниз либо до следующего HO C, либо до самого компонента. Если вы не включите реквизиты, которые уже были переданы ему, в то, что вы возвращаете в реквизиты, они не будут переданы компоненту. Вам нужно сделать что-то подобное для каждой props функции:

props: ({ mutate, ownProps }) => ({
  finishAssessment: (id) => {
    //
  },
  ...ownProps,
}),

Составление HOC - это боль, и graphql HO C все равно не рекомендуется в пользу хуков. Я бы настоятельно рекомендовал перейти на хуки API.

...