diff --git a/Changelog b/Changelog index ac91066037..c1e61aa09a 100644 --- a/Changelog +++ b/Changelog @@ -2,9 +2,41 @@ Expect active development and potentially significant breaking changes in the `0.x` track. We'll try to be diligent about releasing a `1.0` version in a timely fashion (ideally within 1 or 2 months), so that we can take advantage of SemVer to signify breaking changes from that point on. +### v0.2.0 + +**Breaking change:** + +Remove `result` key in favor of dynamic key matching root fields of the query or mutation. (https://github.com/apollostack/react-apollo/pull/31) + +```js +{ + loading: false, + result: { + posts: [] + } +} +``` + +becomes + +```js +{ + loading: false, + posts: [] +} +``` + +### v0.1.5 + +Get state directly from redux store internally + +### v0.1.4 + +Fix bug with willReceiveProps + ### v0.1.2 -Adjust loading lifecycle marker to better match the behavoir of apollo-client (https://github.com/apollostack/react-apollo/pull/11) +Adjust loading lifecycle marker to better match the behavior of apollo-client (https://github.com/apollostack/react-apollo/pull/11) ### v0.1.1 diff --git a/package.json b/package.json index 69c126d659..622a165964 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-apollo", - "version": "0.1.6", + "version": "0.2.0", "description": "React data container for Apollo Client", "main": "./lib/src/index.js", "scripts": { diff --git a/src/connect.tsx b/src/connect.tsx index 5fabbe0398..ab71bd6a37 100644 --- a/src/connect.tsx +++ b/src/connect.tsx @@ -53,7 +53,6 @@ const defaultMapMutationsToProps = opts => ({ }); const defaultQueryData = { loading: true, errors: null, - result: null, }; const defaultMutationData = assign({}, defaultQueryData); @@ -87,7 +86,7 @@ export default function connect(opts?: ConnectOptions) { { loading: boolean, errors: Errors, - result: GraphQLResult, + [key: String]: result } */ @@ -214,11 +213,10 @@ export default function connect(opts?: ConnectOptions) { variables, }); - queryData = { + queryData = assign({ errors: null, loading: false, - result, - }; + }, result); } catch (e) {/* tslint */} this.data[key] = queryData; @@ -262,13 +260,24 @@ export default function connect(opts?: ConnectOptions) { }; }; - const forceRender = ({ errors, data }: any) => { - this.data[key] = { + const forceRender = ({ errors, data = {} }: any) => { + const resultKeyConflict: boolean = ( + 'errors' in data || + 'loading' in data || + 'refetch' in data + ); + + invariant(!resultKeyConflict, + `the result of the '${key}' query contains keys that ` + + `conflict with the return object. 'errors', 'loading', and 'refetch' cannot be ` + + `returned keys` + ); + + this.data[key] = assign({ loading: false, - result: data || null, errors, refetch: refetch, // copy over refetch method - }; + }, data); this.hasQueryDataChanged = true; @@ -318,12 +327,23 @@ export default function connect(opts?: ConnectOptions) { // middleware to update the props to send data to wrapped component // when the mutation is done - const forceRender = ({ errors, data }: GraphQLResult): GraphQLResult => { - this.data[key] = { + const forceRender = ({ errors, data = {} }: GraphQLResult): GraphQLResult => { + const resultKeyConflict: boolean = ( + 'errors' in data || + 'loading' in data || + 'refetch' in data + ); + + invariant(!resultKeyConflict, + `the result of the '${key}' mutation contains keys that ` + + `conflict with the return object. 'errors', 'loading', and 'refetch' cannot be ` + + `returned keys` + ); + + this.data[key] = assign({ loading: false, - result: data, errors, - }; + }, data); this.hasMutationDataChanged = true; diff --git a/test/connect.tsx b/test/connect.tsx index f45dd458b9..ef3330c4c0 100644 --- a/test/connect.tsx +++ b/test/connect.tsx @@ -693,7 +693,7 @@ describe('connect', () => { if (this.props.people.loading) { expect(this.props.people.loading).to.be.true; - expect(this.props.people.result).to.exist; + expect(this.props.people.allPeople).to.exist; done(); } @@ -1050,7 +1050,7 @@ describe('connect', () => { class Container extends React.Component { componentDidUpdate(prevProps) { expect(prevProps.luke.loading).to.be.true; - expect(this.props.luke.result).to.deep.equal(data); + expect(this.props.luke.luke).to.deep.equal(data.luke); done(); } render() { @@ -1131,7 +1131,7 @@ describe('connect', () => { expect(props.people).to.exist; expect(props.people.loading).to.be.false; - expect(props.people.result).to.deep.equal(data); + expect(props.people.allPeople).to.deep.equal(data.allPeople); done(); }); }); @@ -1435,7 +1435,7 @@ describe('connect', () => { // wait until finished loading if (!this.props.makeListPrivate.loading) { expect(prevProps.makeListPrivate.loading).to.be.true; - expect(this.props.makeListPrivate.result).to.deep.equal(data); + expect(this.props.makeListPrivate.makeListPrivate).to.be.true; done(); } } @@ -1506,7 +1506,7 @@ describe('connect', () => { componentDidUpdate(prevProps) { if (!this.props.makeListPrivate.loading) { expect(prevProps.makeListPrivate.loading).to.be.true; - expect(this.props.makeListPrivate.result).to.deep.equal(data); + expect(this.props.makeListPrivate.makeListPrivate).to.be.true; done(); } } @@ -1577,7 +1577,7 @@ describe('connect', () => { componentDidUpdate(prevProps) { if (!this.props.makeListPrivate.loading) { expect(prevProps.makeListPrivate.loading).to.be.true; - expect(this.props.makeListPrivate.result).to.deep.equal(data); + expect(this.props.makeListPrivate.makeListPrivate).to.be.true; done(); } } @@ -1644,7 +1644,7 @@ describe('connect', () => { componentDidUpdate(prevProps) { if (!this.props.makeListPrivate.loading) { expect(prevProps.makeListPrivate.loading).to.be.true; - expect(this.props.makeListPrivate.result).to.deep.equal(data); + expect(this.props.makeListPrivate.makeListPrivate).to.be.true; done(); } }