diff --git a/Changelog.md b/Changelog.md
index 51800fd82f..e8dd1eccfa 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -4,6 +4,10 @@ Expect active development and potentially significant breaking changes in the `0
### vNext
+### v0.5.4
+
+- Bug: Created better reference to updateQuery when bound early. It will also throw if called before it should be.
+
### v0.5.3
- Bug: Fixed issue with updateQuery not being present during componentWillMount [#203](https://github.com/apollostack/react-apollo/pull/203)
diff --git a/package.json b/package.json
index 2ebafd2d55..4bafc971d0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-apollo",
- "version": "0.5.3",
+ "version": "0.5.4",
"description": "React data container for Apollo Client",
"main": "index.js",
"scripts": {
diff --git a/src/graphql.tsx b/src/graphql.tsx
index 0dec2c96c0..5f3ca1bf4c 100644
--- a/src/graphql.tsx
+++ b/src/graphql.tsx
@@ -253,7 +253,6 @@ export default function graphql(
// request / action storage
private queryObservable: ObservableQuery | Object;
private querySubscription: Subscription | Object;
- private updateQueryMethod: any;
// calculated switches to control rerenders
private haveOwnPropsChanged: boolean;
@@ -352,7 +351,14 @@ export default function graphql(
};
// XXX type this better
- queryData.updateQuery = (mapFn: any) => this.updateQueryMethod = mapFn;
+ // this is a stub for early binding of updateQuery before data
+ queryData.updateQuery = (mapFn: any) => {
+ invariant(!!(this.queryObservable as ObservableQuery).updateQuery, `
+ Update query has been called before query has been created
+ `);
+
+ (this.queryObservable as ObservableQuery).updateQuery(mapFn);
+ };
if (!forceFetch) {
try {
@@ -421,9 +427,6 @@ export default function graphql(
const observableQuery = watchQuery(queryOptions);
const { queryId } = observableQuery;
- // bind any eariler set updateQuery method
- if (this.updateQueryMethod) observableQuery.updateQuery(this.updateQueryMethod);
-
// the shape of the query has changed
if (previousQuery.queryId && previousQuery.queryId !== queryId) {
this.data = assign(this.data, { loading: true });
diff --git a/test/react-web/client/graphql/queries.tsx b/test/react-web/client/graphql/queries.tsx
index 9097134288..5b5c0f5e73 100644
--- a/test/react-web/client/graphql/queries.tsx
+++ b/test/react-web/client/graphql/queries.tsx
@@ -1184,7 +1184,6 @@ describe('queries', () => {
componentWillMount() { // tslint:disable-line
expect(this.props.data.updateQuery).to.be.exist;
expect(this.props.data.updateQuery).to.be.instanceof(Function);
- expect(this.props.data.updateQuery).to.not.throw;
done();
}
render() {
@@ -1195,6 +1194,70 @@ describe('queries', () => {
mount();
});
+ it('updateQuery throws if called before data has returned', (done) => {
+ const query = gql`query people { allPeople(first: 1) { people { name } } }`;
+ const data = { allPeople: { people: [ { name: 'Luke Skywalker' } ] } };
+ const networkInterface = mockNetworkInterface({ request: { query }, result: { data } });
+ const client = new ApolloClient({ networkInterface });
+
+ @graphql(query)
+ class Container extends React.Component {
+ componentWillMount() { // tslint:disable-line
+ expect(this.props.data.updateQuery).to.be.exist;
+ expect(this.props.data.updateQuery).to.be.instanceof(Function);
+ try {
+ this.props.data.updateQuery();
+ done(new Error('should have thrown'))
+ } catch (e) {
+ expect(e).to.match(/Invariant Violation:/);
+ done();
+ }
+ }
+ render() {
+ return null;
+ }
+ };
+
+ mount();
+ });
+
+ it('allows updating query results after query has finished (early binding)', (done) => {
+ const query = gql`query people { allPeople(first: 1) { people { name } } }`;
+ const data = { allPeople: { people: [ { name: 'Luke Skywalker' } ] } };
+ const data2 = { allPeople: { people: [ { name: 'Leia Skywalker' } ] } };
+ const networkInterface = mockNetworkInterface(
+ { request: { query }, result: { data } },
+ { request: { query }, result: { data: data2 } }
+ );
+ const client = new ApolloClient({ networkInterface });
+
+ let isUpdated;
+ @graphql(query)
+ class Container extends React.Component {
+ public updateQuery: any;
+ componentWillMount() {
+ this.updateQuery = this.props.data.updateQuery;
+ }
+ componentWillReceiveProps(props) {
+ if (isUpdated) {
+ expect(props.data.allPeople).to.deep.equal(data2.allPeople);
+ done();
+ return;
+ } else {
+ isUpdated = true;
+ this.updateQuery((prev) => {
+ return data2;
+ });
+ }
+ }
+ render() {
+ return null;
+ }
+ };
+
+ mount();
+ });
+
it('allows updating query results after query has finished', (done) => {
const query = gql`query people { allPeople(first: 1) { people { name } } }`;
const data = { allPeople: { people: [ { name: 'Luke Skywalker' } ] } };