Skip to content

Instantly share code, notes, and snippets.

@andreisebastianc
Last active September 4, 2017 13:40
Show Gist options
  • Save andreisebastianc/ecf589bfd966b0bef4a724073e118623 to your computer and use it in GitHub Desktop.
Save andreisebastianc/ecf589bfd966b0bef4a724073e118623 to your computer and use it in GitHub Desktop.
Glimmer that receives redux store from outside the compiled webcomponent
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Hello Glimmer</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="/ember-cli-live-reload.js" type="text/javascript"></script>
<link rel="stylesheet" href="app.css">
<script>
// @note hack for the redux npm
window.process = {
env: {
NODE_ENV: JSON.stringify('production')
}
}
</script>
</head>
<body>
<div class="web-component-wrapper">
<redux-with-events />
</div>
<div class="web-component-wrapper">
<redux-app />
</div>
<script src="app.js"></script>
<script src="redux-app.js"></script>
<script defer>
const els = document.querySelectorAll('.web-component-wrapper')
let event;
els.forEach(function(el) {
el.addEventListener('didInsert', function(ev) {
event = new CustomEvent(ev.detail.id, {
detail: {
ref: {},
message: 'store would be here'
}
});
el.dispatchEvent(event);
});
});
</script>
</body>
</html>
import Component, { tracked } from '@glimmer/component';
import 'regenerator-runtime/runtime';
import trackService from '../../../utils/tracked';
import Redux from '../../../services/redux';
const INGEST_EVENT = 'call-me';
const NOTIFY_EVENT = 'didInsert';
function externalStore(storePropName: string) {
return (ctor: Function) => {
const originalMethod = ctor.prototype.didInsertElement;
ctor.prototype.didInsertElement = function() {
const event = new CustomEvent(NOTIFY_EVENT, {
bubbles: true,
detail: { id: INGEST_EVENT }
});
const target = this.element.parentElement;
const handler = (event) => {
// event.detail contains whatever external app sends
console.log(event.detail.message);
// ref should be the store
console.log(event.detail.ref);
console.log(this[storePropName]);
// @note confirms that setter works
this[storePropName] = new Redux();
/////
console.log('removed event listener');
target.removeEventListener(INGEST_EVENT, handler);
};
target.addEventListener(INGEST_EVENT, handler);
this.element.dispatchEvent(event);
originalMethod.apply(this, ...arguments);
}
}
}
function externalStoreMethod(storePropName) {
return function (target, key, descriptor) {
if(descriptor === undefined) {
descriptor = Object.getOwnPropertyDescriptor(target, key);
}
const originalMethod = descriptor.value;
descriptor.value = function () {
const event = new CustomEvent(NOTIFY_EVENT, {
bubbles: true,
detail: { id: INGEST_EVENT }
});
// const target = this.element.parentElement;
const target = this.element.parentElement;
const handler = (event) => {
// event.detail contains whatever external app sends
console.log(event.detail.message);
// ref should be the store
console.log(event.detail.ref);
console.log(this[storePropName]);
// @note confirms that setter works
this[storePropName] = new Redux();
/////
console.log('removed event listener');
target.removeEventListener(INGEST_EVENT, handler);
};
target.addEventListener(INGEST_EVENT, handler);
this.element.dispatchEvent(event);
const result = originalMethod.apply(this, ...arguments);
return result;
};
return descriptor;
}
}
@trackService('redux')
@externalStore('redux')
export default class ReduxComponent extends Component {
redux: Redux;
// @note this doesn't work
@tracked('redux')
handleStoreAvailable() {
this.loadNames()
}
@tracked
persons: Array<Person> = null;
constructor(options) {
super(options);
}
//@externalStoreMethod('redux')
didInsertElement() {
this.loadNames()
}
async loadNames() {
const req = await fetch('http://uinames.com/api/?amount=25');
const persons = await req.json();
this.redux.store.dispatch({
type: 'LOAD',
persons: persons
});
}
}
import Service from './-utils/service';
import { createStore } from 'redux';
import { tracked } from '@glimmer/component';
import persons from './reducers/persons';
export interface Person {
name: string,
surname: string,
gender: string,
region: string
}
export default class Redux extends Service {
store: any;
constructor(options) {
super(options);
this.store = createStore(
persons,
window['__REDUX_DEVTOOLS_EXTENSION__'] && window['__REDUX_DEVTOOLS_EXTENSION__']()
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment