Last active
November 2, 2017 00:26
-
-
Save MHerszak/17e39b85db4f7c6e70fc40e95da21dc4 to your computer and use it in GitHub Desktop.
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 { APP_REST } from './../../components/constants'; | |
import { setDisplayName } from './utils'; | |
import { forEach, map, arrayIsEmpty } 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) => { | |
console.log(result._id); | |
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) { | |
// console.log('service in doc = .', 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('state in docStarget => ', state); | |
console.log('props in docStarget => ', props); | |
console.log('result in docStarget => ', result); | |
// console.log('service in docStrategy => ', this.service); | |
return result; | |
} | |
} | |
function getStrategy(options) { | |
return options.strategy ? options.strategy : new DocumentStrategy(); | |
} | |
function withStrategyCallback(callback) { | |
return function stateFunctionHOC(result) { | |
return function stateFunction(state, props) { | |
// callback will be false or a callback | |
return { | |
data: callback.call(this, result, state, props) | |
}; | |
}; | |
}; | |
} | |
function withService(eventType, callback) { | |
const handler = withStrategyCallback(callback); | |
return function getResult(result) { | |
switch (eventType) { | |
case 'created': | |
return handler(result); | |
case 'updated': | |
return handler(result); | |
case 'patched': | |
return handler(result); | |
default: | |
console.error('event is not supported'); | |
} | |
}; | |
} | |
const defaultEventTypes = ['created', 'updated', 'removed', 'patched']; | |
// const manualEventTypes = ['patched']; | |
/** | |
* This function takes a service name ... | |
* @param serviceName | |
* @returns {rc} | |
*/ | |
export default function withSubscription(serviceName) { | |
/** | |
* The service will be plugged into app context. | |
* options: updated, created, patched, removed all functions | |
*/ | |
return function rc(WrappedComponent, options = {}) { | |
// Set context types | |
const contextTypes = { | |
...APP_REST | |
}; | |
/** | |
* Context of subscription hoc | |
*/ | |
class WithSubscription extends PureComponent { | |
static contextTypes = contextTypes; | |
constructor(props, context) { | |
super(props, context); | |
// Set options | |
this.options = options; | |
// get keys from object | |
const keys = Object.keys(options) | |
// and filter for default keys | |
.filter((key) => | |
defaultEventTypes.includes(key)); | |
// filter for attached events | |
this.events = arrayIsEmpty(keys) ? defaultEventTypes : [...keys]; | |
// set strategy | |
this.strategy = getStrategy(options); | |
// | |
this.state = { | |
data: this.strategy.type(this.options.data), | |
}; | |
// make sure context exists | |
const { app } = context; | |
// console.log('app.service', app.service); | |
// ... that takes care of the subscription... | |
this.service = app.service(serviceName); | |
// | |
this.strategy.setService(app.service(serviceName)); | |
} | |
componentDidMount() { | |
// const { app } = this.context; | |
// // ... that takes care of the subscription... | |
console.log(this.events); | |
// | |
forEach(this.events, (eventType) => { | |
// created, updated, patched and removed | |
this.service.on(eventType, this.handleChange(eventType)); | |
}); | |
} | |
componentWillUnmount() { | |
// const { app } = this.context; | |
// // | |
// const service = app.service(serviceName); | |
// | |
forEach(this.events, (eventType) => { | |
// created, updated, patched and removed | |
this.service.removeListener(eventType, this.handleChange(eventType)); | |
}); | |
} | |
handleChange = (eventType = '') => (result) => { | |
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; | |
}; | |
} | |
// const BlogWithFeathersSubscription = (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