Skip to content

Instantly share code, notes, and snippets.

@MHerszak
Last active November 2, 2017 00:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MHerszak/17e39b85db4f7c6e70fc40e95da21dc4 to your computer and use it in GitHub Desktop.
Save MHerszak/17e39b85db4f7c6e70fc40e95da21dc4 to your computer and use it in GitHub Desktop.
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