@department/apollo-component
Advanced tools
Comparing version 1.3.0 to 1.4.0
@@ -7,4 +7,3 @@ 'use strict'; | ||
var React = require('react'); | ||
var React__default = _interopDefault(React); | ||
var React = _interopDefault(require('react')); | ||
var PropTypes = _interopDefault(require('prop-types')); | ||
@@ -37,5 +36,10 @@ var reactDom = require('react-dom'); | ||
Query.prototype.componentWillMount = function componentWillMount () { | ||
var ref = this.context.apollo; | ||
var ref = this.context.apollo || {}; | ||
var client = ref.client; | ||
var queries = ref.queries; | ||
if (!client) { | ||
throw new Error( | ||
"missing apollo client in context. is there a <Provider /> ancestor component?" | ||
); | ||
} | ||
@@ -82,6 +86,10 @@ this.observable = client.watchQuery(propsToOptions(this.props)); | ||
if (!this.subscription) { | ||
var debounce; | ||
var update = function () { | ||
if (this$1.mounted) { | ||
this$1.forceUpdate(); | ||
} | ||
cancelAnimationFrame(debounce); | ||
debounce = requestAnimationFrame(function () { | ||
if (this$1.mounted) { | ||
this$1.forceUpdate(); | ||
} | ||
}); | ||
}; | ||
@@ -100,11 +108,10 @@ this.subscription = this.observable.subscribe({ | ||
var data = {}; | ||
// Let's do what we can to give the user data | ||
if (loading) { | ||
Object.assign(data, this.previousData, currentResult.data); | ||
} else if (error) { | ||
if (error) { | ||
Object.assign(data, (this.observable.getLastResult() || {}).data); | ||
} else { | ||
this.previousData = currentResult.data; | ||
Object.assign(data, currentResult.data); | ||
Object.assign(data, this.previousData, currentResult.data); | ||
} | ||
this.previousData = data; | ||
return { | ||
@@ -118,4 +125,9 @@ loading: loading, | ||
Query.prototype.refetch = function refetch (vars) { | ||
if ( vars === void 0 ) vars = this.props.variables; | ||
if (this.observable) { | ||
return this.observable.refetch(vars); | ||
// special case for when vars are event | ||
// ex. <button onClick={refetch} /> | ||
var isPlainObj = typeof vars == "object" && vars.constructor == Object; | ||
return this.observable.refetch(isPlainObj ? vars : undefined); | ||
} | ||
@@ -153,3 +165,3 @@ }; | ||
return Query; | ||
}(React__default.Component)); | ||
}(React.Component)); | ||
@@ -203,3 +215,7 @@ Query.contextTypes = { | ||
// see https://www.apollographql.com/docs/react/basics/queries.html#graphql-config-options-context | ||
context: PropTypes.object | ||
context: PropTypes.object, | ||
// Render using either the `children`- or a `render`-prop callback | ||
children: PropTypes.func, | ||
render: PropTypes.func | ||
}; | ||
@@ -311,2 +327,7 @@ | ||
Mutate.prototype.render = function render$$1 () { | ||
// <Mutate fail> will throw the error instead of using the callback | ||
if (this.props.fail && state.error) { | ||
throw state.error; | ||
} | ||
return (this.props.render || this.props.children)(this.mutate, this.state); | ||
@@ -316,3 +337,3 @@ }; | ||
return Mutate; | ||
}(React__default.Component)); | ||
}(React.Component)); | ||
@@ -325,2 +346,24 @@ Mutate.contextTypes = { | ||
Mutate.propTypes = { | ||
// A graphql-tag compiled gql query | ||
gql: PropTypes.object.isRequired, | ||
// Fail by throwing an exception and letting the React error boundary | ||
// take care of it instead of passing the error into the render callback | ||
fail: PropTypes.bool, | ||
// see https://www.apollographql.com/docs/react/basics/mutations.html#graphql-mutation-options-refetchQueries | ||
refetchQueries: PropTypes.array, | ||
// see https://www.apollographql.com/docs/react/basics/mutations.html#graphql-mutation-options-optimisticResponse | ||
optimisticResponse: PropTypes.func, | ||
// see https://www.apollographql.com/docs/react/basics/mutations.html#graphql-mutation-options-update | ||
update: PropTypes.func, | ||
// Render using either the `children`- or a `render`-prop callback | ||
children: PropTypes.func, | ||
render: PropTypes.func | ||
}; | ||
var Provider = (function (superclass) { | ||
@@ -349,3 +392,3 @@ function Provider () { | ||
return Provider; | ||
}(React__default.Component)); | ||
}(React.Component)); | ||
@@ -397,16 +440,26 @@ Provider.childContextTypes = { | ||
function renderToDOM(component) { | ||
var element = document.createElement("div"); | ||
reactDom.render(component, element); | ||
reactDom.render(component, document.createDocumentFragment()); | ||
} | ||
var renderState = function (client, component, ref) { | ||
var renderState = function ( | ||
client, | ||
component, | ||
ref | ||
) { | ||
if ( ref === void 0 ) ref = {}; | ||
var depth = ref.depth; if ( depth === void 0 ) depth = Infinity; | ||
var maxDepth = ref.maxDepth; if ( maxDepth === void 0 ) maxDepth = Infinity; | ||
var renderer = client.ssrMode ? server.renderToStaticMarkup : renderToDOM; | ||
var render$$1 = function () { | ||
var render$$1 = function (depth) { | ||
if ( depth === void 0 ) depth = 0; | ||
var queries = []; | ||
renderer(React.createElement(Provider, { client: client, queries: queries }, component)); | ||
renderer( | ||
React.createElement( Provider, { client: client, queries: queries }, | ||
component | ||
) | ||
); | ||
var queue = queries | ||
@@ -420,3 +473,3 @@ .filter(function (q) { return q.currentResult().loading; }) | ||
// try to go deeper if we succeed | ||
.then(function () { return --depth && render$$1(); }) | ||
.then(function () { return depth < maxDepth && render$$1(depth + 1); }) | ||
); | ||
@@ -423,0 +476,0 @@ } |
{ | ||
"name": "@department/apollo-component", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "Render component for your Apollo Client", | ||
"repository": "department-stockholm/apollo-component", | ||
"homepage": "https://github.com/department-stockholm/apollo-component", | ||
"bugs": "https://github.com/department-stockholm/apollo-component/issues", | ||
"main": "dist/index.cjs.js", | ||
@@ -12,3 +15,5 @@ "jsnext:main": "dist/index.esm.mjs", | ||
"build": "rollup -c", | ||
"prepare": "rollup -c" | ||
"prepare": "rollup -c", | ||
"release": "release", | ||
"postpublish": "release" | ||
}, | ||
@@ -28,5 +33,6 @@ "author": "Robert Sköld (https://department.se)", | ||
"react-dom": "^16.1.0", | ||
"release": "^2.5.6", | ||
"rollup": "^0.51.5", | ||
"rollup-plugin-buble": "^0.17.0" | ||
"rollup-plugin-buble": "^0.18.0" | ||
} | ||
} |
133
README.md
# Apollo Component | ||
[![npm version](https://badge.fury.io/js/%40department%2Fapollo-component.svg)](https://badge.fury.io/js/%40department%2Fapollo-component) | ||
A render component for easy querying and mutating of your GraphQL API. | ||
## Example | ||
## Install | ||
Here is an example of fetching and rendering the data | ||
of an imaginary `Order`. | ||
```sh | ||
npm install @department/apollo-component | ||
``` | ||
## Examples | ||
Here is an example of fetching and rendering the data of an imaginary `Order`. | ||
```js | ||
import SingleOrder, {LoadingOrder} from "components/SingleOrder" | ||
import { gql } from "graphql-tag" | ||
import { Query } from "@department/apollo-component" | ||
import SingleOrder, { LoadingOrder } from "components/SingleOrder" | ||
import { GenericError, NotFound } from "components/Errors" | ||
@@ -35,3 +44,40 @@ | ||
)); | ||
``` | ||
And another example using `<Mutate/>` and `fail`-props to raise any errors to | ||
the nearest | ||
[React 16+ Error Boundary](https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html): | ||
```js | ||
import { gql } from "graphql-tag"; | ||
import { Mutate, Query } from "@department/apollo-component"; | ||
import { Exception } from "components/Exception"; | ||
const IncrementMutation = gql` | ||
mutation IncrementMutation($num: Int!) { | ||
incr(num: $num) | ||
} | ||
`; | ||
const ShowCountQuery = gql` | ||
query ShowCount { | ||
count | ||
} | ||
`; | ||
const IncrementView = ({ id }) => ( | ||
<Exception> | ||
<Query gql={ShowCount} wait fail> | ||
{({ data: { count } }) => <div>Current count: {count}</div>} | ||
</Query> | ||
<Mutate gql={IncrementMutation} refetchQueries={["ShowCount"]} fail> | ||
{incr => ( | ||
<form onSubmit={e => incr({ num: e.currentTarget.num.valueAsNumber })}> | ||
<input type="number" name="num" value={1} step={1} /> | ||
<button>+</button> | ||
</form> | ||
)} | ||
</Mutate> | ||
</Exception> | ||
); | ||
``` | ||
@@ -41,34 +87,57 @@ | ||
### <Query /> | ||
### `<Query />` | ||
Available Props: | ||
- gql | ||
- wait | ||
- lazy | ||
- fail | ||
- variables | ||
[Available Props](https://github.com/department-stockholm/apollo-component/blob/master/Query.js#L142-L187): | ||
Arguments in render callback: | ||
- QueryResults | ||
- data | ||
- loading | ||
- error | ||
- refetch | ||
- fetchMore | ||
* `gql` | ||
* `wait` | ||
* `lazy` | ||
* `fail` | ||
* `variables` | ||
### <Mutate /> | ||
#### Arguments in render callback | ||
Available Props: | ||
- gql | ||
- refetchQueries | ||
- optimisticResponse | ||
- update | ||
* _QueryResults_ | ||
* `data` the loaded data or an empty object | ||
* `loading` true while loading (unless the `wait`-prop was set) | ||
* `error` Error object if there was any error (unless the `fail`-props was | ||
set) | ||
* `refetch(variables)` call this function rerun query with, optionally, new | ||
variables | ||
* `fetchMore(opts)` call this function to fetch more (read about the | ||
[opts](https://www.apollographql.com/docs/react/basics/queries.html#graphql-query-data-fetchMore)) | ||
Arguments in render callback: | ||
- Mutate(variables) | ||
- QueryResults | ||
- data | ||
- loading | ||
- error | ||
- refetch | ||
- fetchMore | ||
##### Example: | ||
```js | ||
({ data: { stuff }, loading }) => <div>{loading ? "loading..." : stuff}</div>; | ||
``` | ||
### `<Mutate />` | ||
[Available Props](https://github.com/department-stockholm/apollo-component/blob/master/Mutate.js#L86-L106): | ||
* `gql` | ||
* `refetchQueries` | ||
* `optimisticResponse` | ||
* `update` | ||
#### Arguments in render callback | ||
* `Mutate(variables)` call this function to trigger the mutation | ||
* _QueryResults_ (same as for Query) | ||
* `data` | ||
* `loading` | ||
* `error` | ||
* `refetch` | ||
* `fetchMore` | ||
##### Example: | ||
```js | ||
(mutate, { data: { stuff }, loading }) => ( | ||
<button onClick={() => mutate()} disabled={loading}> | ||
{loading ? "loading..." : stuff} | ||
</button> | ||
); | ||
``` |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
18210
4
393
0
142
0
8