From 373404b5b733afa1c28247ee5f71a89e9ddb00a6 Mon Sep 17 00:00:00 2001 From: Hagai Cohen Date: Thu, 13 Oct 2016 20:36:01 +0300 Subject: [PATCH] single interface for fetch (#172) * single interface for fetch (observables becomes promises when it expects only one value) --- src/components/GraphiQL.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/components/GraphiQL.js b/src/components/GraphiQL.js index 2c75391c9c4..c1c7d5cb849 100644 --- a/src/components/GraphiQL.js +++ b/src/components/GraphiQL.js @@ -420,7 +420,7 @@ export class GraphiQL extends React.Component { const fetcher = this.props.fetcher; - const fetch = fetcher({ query: introspectionQuery }); + const fetch = observableToPromise(fetcher({ query: introspectionQuery })); if (!isPromise(fetch)) { this.setState({ response: 'Fetcher did not return a Promise for introspection.' @@ -435,7 +435,9 @@ export class GraphiQL extends React.Component { // Try the stock introspection query first, falling back on the // sans-subscriptions query for services which do not yet support it. - const fetch2 = fetcher({ query: introspectionQuerySansSubscriptions }); + const fetch2 = observableToPromise(fetcher({ + query: introspectionQuerySansSubscriptions + })); if (!isPromise(fetch)) { throw new Error('Fetcher did not return a Promise for introspection.'); } @@ -895,6 +897,23 @@ function isPromise(value) { return typeof value === 'object' && typeof value.then === 'function'; } +// Duck-type Observable.take(1).toPromise() +function observableToPromise(observable) { + if ( !isObservable(observable) ) { + return observable; + } + return new Promise((resolve, reject) => { + const subscription = observable.subscribe(v => { + resolve(v); + subscription.unsubscribe(); + }, e => { + reject(e); + }, () => { + reject(new Error('no value resolved')); + }); + }); +} + // Duck-type observable detection. function isObservable(value) { return typeof value === 'object' && typeof value.subscribe === 'function';