Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Commit

Permalink
Added a "called" field in the result prop of the mutation to make des…
Browse files Browse the repository at this point in the history
…tructuring easier. (#1775)
  • Loading branch information
excitement-engineer authored and James Baxley committed Mar 16, 2018
1 parent 76db01e commit fede11c
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 42 deletions.
31 changes: 17 additions & 14 deletions src/Mutation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { parser, DocumentType } from './parser';
export interface MutationResult<TData = Record<string, any>> {
data?: TData;
error?: ApolloError;
loading?: boolean;
loading: boolean;
called: boolean;
}
export interface MutationContext {
client: ApolloClient<Object>;
Expand Down Expand Up @@ -55,22 +56,25 @@ export interface MutationProps<TData = any, TVariables = OperationVariables> {
update?: MutationUpdaterFn<TData>;
children: (
mutateFn: (options?: MutationOptions<TData, TVariables>) => Promise<void | FetchResult>,
result?: MutationResult<TData>,
result: MutationResult<TData>,
) => React.ReactNode;
onCompleted?: (data: TData) => void;
onError?: (error: ApolloError) => void;
context?: Record<string, any>;
}

export interface MutationState<TData = any> {
notCalled: boolean;
called: boolean;
error?: ApolloError;
data?: TData;
loading?: boolean;
loading: boolean;
}

const initialState = {
notCalled: true,
loading: false,
called: false,
error: undefined,
data: undefined,
};

class Mutation<TData = any, TVariables = OperationVariables> extends React.Component<
Expand Down Expand Up @@ -132,15 +136,14 @@ class Mutation<TData = any, TVariables = OperationVariables> extends React.Compo

render() {
const { children } = this.props;
const { loading, data, error, notCalled } = this.state;
const { loading, data, error, called } = this.state;

const result = notCalled
? undefined
: {
loading,
data,
error,
};
const result = {
called,
loading,
data,
error,
};

return children(this.runMutation, result);
}
Expand Down Expand Up @@ -197,7 +200,7 @@ class Mutation<TData = any, TVariables = OperationVariables> extends React.Compo
loading: true,
error: undefined,
data: undefined,
notCalled: false,
called: true,
});
}
};
Expand Down
77 changes: 49 additions & 28 deletions test/client/Mutation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,21 @@ it('performs a mutation', done => {
<Mutation mutation={mutation}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
expect(result).toEqual({
loading: false,
called: false,
});
setTimeout(() => {
createTodo();
});
} else if (count === 1) {
expect(result).toEqual({
called: true,
loading: true,
});
} else if (count === 2) {
expect(result).toEqual({
called: true,
loading: false,
data,
});
Expand All @@ -106,7 +111,10 @@ it('can bind only the mutation and not rerender by props', done => {
<Mutation mutation={mutation} ignoreResults>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
expect(result).toEqual({
loading: false,
called: false,
});
setTimeout(() => {
createTodo().then(r => {
expect(r!.data).toEqual(data);
Expand Down Expand Up @@ -190,6 +198,7 @@ it('returns rejected promise when calling the mutation function', done => {
</MockedProvider>,
);
});

it('only shows result for the latest mutation that is in flight', done => {
let count = 0;

Expand All @@ -205,18 +214,24 @@ it('only shows result for the latest mutation that is in flight', done => {
<Mutation mutation={mutation} onCompleted={onCompleted}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
expect(result).toEqual({
called: false,
loading: false,
});

setTimeout(() => {
createTodo();
createTodo();
});
} else if (count === 1) {
expect(result).toEqual({
loading: true,
called: true,
});
} else if (count === 2) {
expect(result).toEqual({
loading: false,
called: true,
data: data2,
});
}
Expand Down Expand Up @@ -248,19 +263,24 @@ it('only shows the error for the latest mutation in flight', done => {
<Mutation mutation={mutation} onError={onError}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
expect(result).toEqual({
called: false,
loading: false,
});
setTimeout(() => {
createTodo();
createTodo();
});
} else if (count === 1) {
expect(result).toEqual({
loading: true,
called: true,
});
} else if (count === 2) {
expect(result).toEqual({
loading: false,
data: undefined,
called: true,
error: new Error('Network error: Error 2'),
});
}
Expand Down Expand Up @@ -308,7 +328,7 @@ it('calls the onCompleted prop as soon as the mutation is complete', done => {
return (
<Mutation mutation={mutation} onCompleted={this.onCompleted}>
{(createTodo, result) => {
if (!result) {
if (!result.called) {
expect(this.state.mutationDone).toBe(false);
setTimeout(() => {
createTodo();
Expand Down Expand Up @@ -354,9 +374,9 @@ it('renders an error state', done => {
expect(err).toEqual(new Error('Network error: error occurred'));
}),
);
} else if (count === 1 && result) {
} else if (count === 1) {
expect(result.loading).toBeTruthy();
} else if (count === 2 && result) {
} else if (count === 2) {
expect(result.error).toEqual(new Error('Network error: error occurred'));
done();
}
Expand Down Expand Up @@ -400,7 +420,7 @@ it('calls the onError prop if the mutation encounters an error', done => {
return (
<Mutation mutation={mutation} onError={this.onError}>
{(createTodo, result) => {
if (!result) {
if (!result.called) {
expect(mutationError).toBe(false);
setTimeout(() => createTodo());
}
Expand Down Expand Up @@ -439,17 +459,18 @@ it('performs a mutation with variables prop', done => {
<Mutation mutation={mutation} variables={variables}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
setTimeout(() => {
createTodo();
});
} else if (count === 1) {
expect(result).toEqual({
loading: true,
called: true,
});
} else if (count === 2) {
expect(result).toEqual({
loading: false,
called: true,
data,
});
done();
Expand Down Expand Up @@ -484,17 +505,18 @@ it('allows passing a variable to the mutate function', done => {
<Mutation mutation={mutation}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
setTimeout(() => {
createTodo({ variables });
});
} else if (count === 1) {
expect(result).toEqual({
loading: true,
called: true,
});
} else if (count === 2) {
expect(result).toEqual({
loading: false,
called: true,
data,
});
done();
Expand Down Expand Up @@ -541,7 +563,6 @@ it('allows an optimistic response prop', done => {
<Mutation mutation={mutation} optimisticResponse={optimisticResponse}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
setTimeout(() => {
createTodo();
const dataInStore = client.cache.extract(true);
Expand All @@ -550,10 +571,12 @@ it('allows an optimistic response prop', done => {
} else if (count === 1) {
expect(result).toEqual({
loading: true,
called: true,
});
} else if (count === 2) {
expect(result).toEqual({
loading: false,
called: true,
data,
});
done();
Expand Down Expand Up @@ -593,19 +616,15 @@ it('allows passing an optimistic response to the mutate function', done => {
<Mutation mutation={mutation}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
setTimeout(() => {
createTodo({ optimisticResponse });
const dataInStore = client.cache.extract(true);
expect(dataInStore['Todo:99']).toEqual(optimisticResponse.createTodo);
});
} else if (count === 1) {
expect(result).toEqual({
loading: true,
});
} else if (count === 2) {
expect(result).toEqual({
loading: false,
called: true,
data,
});
done();
Expand Down Expand Up @@ -680,10 +699,10 @@ it('allows a refetchQueries prop', done => {
setTimeout(() => {
createTodo();
});
} else if (count === 1 && resultMutation) {
} else if (count === 1) {
expect(resultMutation.loading).toBe(true);
expect(resultQuery.loading).toBe(true);
} else if (count === 2 && resultMutation) {
} else if (count === 2) {
expect(resultMutation.loading).toBe(true);
expect(stripSymbols(resultQuery.data)).toEqual(queryData);
done();
Expand Down Expand Up @@ -760,10 +779,10 @@ it('allows refetchQueries to be passed to the mutate function', done => {
setTimeout(() => {
createTodo({ refetchQueries });
});
} else if (count === 1 && resultMutation) {
} else if (count === 1) {
expect(resultMutation.loading).toBe(true);
expect(resultQuery.loading).toBe(true);
} else if (count === 2 && resultMutation) {
} else if (count === 2) {
expect(resultMutation.loading).toBe(true);
expect(stripSymbols(resultQuery.data)).toEqual(queryData);
done();
Expand Down Expand Up @@ -857,17 +876,13 @@ it('allows for overriding the options passed in the props by passing them in the
<Mutation mutation={mutation} variables={variablesProp}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
setTimeout(() => {
createTodo({ variables: variablesMutateFn });
});
} else if (count === 1) {
expect(result).toEqual({
loading: true,
});
} else if (count === 2) {
expect(result).toEqual({
loading: false,
called: true,
data: data2,
});
done();
Expand Down Expand Up @@ -938,7 +953,10 @@ it('updates if the client changes', done => {
<Mutation mutation={mutation}>
{(createTodo, result) => {
if (count === 0) {
expect(result).toBeUndefined();
expect(result).toEqual({
called: false,
loading: false,
});
setTimeout(() => {
createTodo();
});
Expand All @@ -950,11 +968,14 @@ it('updates if the client changes', done => {
});
});
} else if (count === 3) {
expect(result).toBeUndefined();
expect(result).toEqual({
called: false,
loading: false,
});
setTimeout(() => {
createTodo();
});
} else if (count === 5 && result) {
} else if (count === 5) {
expect(result.data).toEqual(data3);
done();
}
Expand Down

0 comments on commit fede11c

Please sign in to comment.