Last active
November 2, 2017 23:09
-
-
Save MHerszak/2e3602d1f59019177360a2fa06298b09 to your computer and use it in GitHub Desktop.
withSubscription2.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PureComponent } from 'react'; | |
import errors from 'feathers-errors'; | |
import { withPreloader } from './../../redux/container'; | |
import { APP_REST } from './../../components/constants'; | |
import { setDisplayName } from './utils'; | |
import { forEach, map } from './../../utils'; | |
class BaseType { | |
constructor(props) { | |
this.document = props; | |
} | |
type(available) { | |
if (available) { | |
return available; | |
} | |
// console.log('Array.isArray(this.document) => ', Array.isArray(this.document)); | |
return Array.isArray(this.document) ? [] : {}; | |
} | |
} | |
export class ArrayStrategy extends BaseType { | |
constructor(collection) { | |
super(collection); | |
this.collection = collection; | |
} | |
setService(service) { | |
this.service = service; | |
} | |
created(result) { | |
return [...this.collection, result]; | |
} | |
updated(result) { | |
const mappResults = map(this.collection, (val) => { | |
if (result._id === val._id) { | |
return Object.assign({}, val, result); | |
} | |
return val; | |
}); | |
return mappResults; | |
} | |
} | |
export class DocumentStrategy extends BaseType { | |
constructor(document) { | |
super(document); | |
this.document = document; | |
this.service = {}; | |
} | |
setService(service) { | |
this.service = service; | |
} | |
created(result) { | |
this.document = result; | |
return this.document; | |
} | |
patched(result) { | |
this.document = result; | |
console.log('patched => ', result); | |
return this.document; | |
} | |
updated(result, state, props) { | |
console.log('props in docStarget => ', props); | |
console.log('result in docStarget => ', result); | |
return result; | |
} | |
} | |
function getStrategy(options = {}) { | |
return options.strategy || new DocumentStrategy(); | |
} | |
function withStrategyCallback(callback) { | |
return function stateFunctionHOC(result) { | |
return function stateFunction(state, props) { | |
return { | |
data: callback.call(this, result, state, props) | |
}; | |
}; | |
}; | |
} | |
function withService(callback) { | |
const handler = withStrategyCallback(callback); | |
return function getResult(result) { | |
return handler(result); | |
}; | |
} | |
const defaultEventTypes = ['created', 'updated', 'removed', 'patched']; | |
/** | |
* This function takes a service name ... | |
* @param serviceName | |
* @returns {rc} | |
*/ | |
export default function withSubscription(serviceName) { | |
/** | |
* The service will be plugged into app context. | |
*/ | |
return function rc(WrappedComponent, options = { key: 'data' }) { | |
// Set context types | |
const contextTypes = { | |
...APP_REST | |
}; | |
/** | |
* Context of subscription hoc | |
*/ | |
@withPreloader(options) | |
class WithSubscription extends PureComponent { | |
static contextTypes = contextTypes; | |
constructor(props, context) { | |
super(props, context); | |
// | |
this.options = options; | |
// get Events | |
this.events = defaultEventTypes; | |
// set Strategy | |
this.strategy = getStrategy(options); | |
// set key for state | |
const key = options.key; | |
// set State | |
this.state = { | |
[key]: props[key], | |
}; | |
// make sure context exists | |
const { app } = context; | |
// Is app actually available? | |
if (!app) { | |
throw new errors.NotFound(options.noErrMsg ? null : 'No app attached to WithSubscription HOC!'); | |
} | |
// ... that takes care of the subscription... | |
this.service = app.service(serviceName); | |
// | |
this.strategy.setService(app.service(serviceName)); | |
} | |
componentDidMount() { | |
// register all events and handlers | |
forEach(this.events, (eventType) => { | |
// created, updated, patched and removed | |
this.service.on(eventType, this.handleChange(eventType)); | |
}); | |
} | |
componentWillUnmount() { | |
// remove all events | |
forEach(this.events, (eventType) => { | |
// created, updated, patched and removed | |
this.service.removeListener(eventType, this.handleChange(eventType)); | |
}); | |
} | |
handleChange = (eventType = '') => (result) => { | |
const handler = withService(this.strategy[eventType]); | |
// const handler = withService(eventType, this.strategy[eventType]); | |
// | |
if (this.component) { | |
return this.setState(handler(result)); | |
} | |
}; | |
render() { | |
// ... and renders the wrapped component with the fresh data! | |
// Notice that we pass through any additional props | |
return ( | |
<WrappedComponent | |
ref={(ref) => { this.component = ref; }} | |
data={this.state.data} | |
{...this.props} | |
/> | |
); | |
} | |
} | |
WithSubscription.displayName = `WithSubscription(${setDisplayName(WrappedComponent)})`; | |
return WithSubscription; | |
}; | |
} | |
// #1 with options | |
// const BlogPostWithSubscription = (service = '') = withSubscription( | |
// BlogPost, { | |
// updated(service, data) { | |
// console.log(data); | |
// } | |
// } | |
// ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment