Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable polling during SSR #1664

Merged
merged 2 commits into from
May 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/ApolloClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export default class ApolloClient implements DataProxy {
private devToolsHookCb: Function;
private proxy: DataProxy | undefined;
private fragmentMatcher: FragmentMatcherInterface;
private ssrMode: boolean;

/**
* Constructs an instance of {@link ApolloClient}.
Expand Down Expand Up @@ -215,6 +216,7 @@ export default class ApolloClient implements DataProxy {
this.dataId = dataIdFromObject = dataIdFromObject || defaultDataIdFromObject;
this.fieldWithArgs = storeKeyNameFromFieldNameAndArgs;
this.queryDeduplication = queryDeduplication;
this.ssrMode = ssrMode;

if (ssrForceFetchDelay) {
setTimeout(() => this.disableNetworkFetches = false, ssrForceFetchDelay);
Expand Down Expand Up @@ -522,6 +524,7 @@ export default class ApolloClient implements DataProxy {
reducerConfig: this.reducerConfig,
queryDeduplication: this.queryDeduplication,
fragmentMatcher: this.fragmentMatcher,
ssrMode: this.ssrMode,
});
}

Expand Down
4 changes: 4 additions & 0 deletions src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export class QueryManager {
public scheduler: QueryScheduler;
public store: ApolloStore;
public networkInterface: NetworkInterface;
public ssrMode: boolean;

private addTypename: boolean;
private deduplicator: Deduplicator;
Expand Down Expand Up @@ -177,6 +178,7 @@ export class QueryManager {
fragmentMatcher,
addTypename = true,
queryDeduplication = false,
ssrMode = false,
}: {
networkInterface: NetworkInterface,
store: ApolloStore,
Expand All @@ -185,6 +187,7 @@ export class QueryManager {
reducerConfig?: ApolloReducerConfig,
addTypename?: boolean,
queryDeduplication?: boolean,
ssrMode?: boolean,
}) {
// XXX this might be the place to do introspection for inserting the `id` into the query? or
// is that the network interface?
Expand All @@ -198,6 +201,7 @@ export class QueryManager {
this.queryDocuments = {};
this.addTypename = addTypename;
this.queryDeduplication = queryDeduplication;
this.ssrMode = ssrMode;

// XXX This logic is duplicated in ApolloClient.ts for two reasons:
// 1. we need it in ApolloClient.ts for readQuery and readFragment of the data proxy.
Expand Down
5 changes: 5 additions & 0 deletions src/scheduler/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ export class QueryScheduler {
throw new Error('Attempted to start a polling query without a polling interval.');
}

if (this.queryManager.ssrMode) {
// Do not poll in SSR mode
return queryId;
}

this.registeredQueries[queryId] = options;

if (listener) {
Expand Down
77 changes: 77 additions & 0 deletions test/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,7 @@ describe('QueryManager', () => {
});

describe('polling queries', () => {

it('allows you to poll queries', () => {
const query = gql`
query fetchLuke($id: String) {
Expand All @@ -1735,6 +1736,7 @@ describe('QueryManager', () => {
name: 'Luke Skywalker has a new name',
},
};

const queryManager = mockQueryManager(
{
request: { query, variables },
Expand All @@ -1759,6 +1761,81 @@ describe('QueryManager', () => {

});

it('does not poll during SSR', (done) => {
const query = gql`
query fetchLuke($id: String) {
people_one(id: $id) {
name
}
}
`;

const variables = {
id: '1',
};

const data1 = {
people_one: {
name: 'Luke Skywalker',
},
};

const data2 = {
people_one: {
name: 'Luke Skywalker has a new name',
},
};

const queryManager = new QueryManager({
networkInterface: mockNetworkInterface({
request: { query, variables },
result: { data: data1 },
},
{
request: { query, variables },
result: { data: data2 },
},
{
request: { query, variables },
result: { data: data2 },
}),
store: createApolloStore(),
reduxRootSelector: defaultReduxRootSelector,
addTypename: false,
ssrMode: true,
});

const observable = queryManager.watchQuery<any>({
query,
variables,
pollInterval: 10,
notifyOnNetworkStatusChange: false,
});

let count = 1;
let doneCalled = false;
const subHandle = observable.subscribe({
next: (result: any) => {
switch (count) {
case 1:
assert.deepEqual(result.data, data1);
setTimeout(() => {
subHandle.unsubscribe();
if (!doneCalled) {
done();
}
}, 15);
count++;
break;
case 2:
default:
doneCalled = true;
done(new Error('Only expected one result, not multiple'));
}
},
});
});

it('should let you handle multiple polled queries and unsubscribe from one of them', (done) => {
const query1 = gql`
query {
Expand Down