diff --git a/packages/vulcan-core/lib/modules/callbacks.js b/packages/vulcan-core/lib/modules/callbacks.js index f9feda082..de80c60fc 100644 --- a/packages/vulcan-core/lib/modules/callbacks.js +++ b/packages/vulcan-core/lib/modules/callbacks.js @@ -1,21 +1,18 @@ import { addCallback, getActions } from 'meteor/vulcan:lib'; /* - - Core callbacks - + + Core callbacks + */ /** * @summary Clear flash messages marked as seen when the route changes - * @param {Object} Item needed by `runCallbacks` to iterate on, unused here - * @param {Object} Redux store reference instantiated on the current connected client - * @param {Object} Apollo Client reference instantiated on the current connected client + * @param {Object} props + * @param {Object} props.client Apollo Client reference instantiated on the current connected client */ -function RouterClearMessages(unusedItem, nextRoute, store, apolloClient) { - store.dispatch(getActions().messages.clearSeen()); - - return unusedItem; +function RouterClearMessages({ client }) { + client.store.dispatch(getActions().messages.clearSeen()); } -addCallback('router.onUpdate', RouterClearMessages); +addCallback('router.onUpdate.async', RouterClearMessages); diff --git a/packages/vulcan-core/lib/modules/components/RouterHook.jsx b/packages/vulcan-core/lib/modules/components/RouterHook.jsx index 9b9254043..1998659f0 100644 --- a/packages/vulcan-core/lib/modules/components/RouterHook.jsx +++ b/packages/vulcan-core/lib/modules/components/RouterHook.jsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { registerComponent, runCallbacks } from 'meteor/vulcan:lib'; +import { registerComponent, runCallbacks, runCallbacksAsync } from 'meteor/vulcan:lib'; import { withApollo } from 'react-apollo'; class RouterHook extends PureComponent { @@ -8,15 +8,17 @@ class RouterHook extends PureComponent { this.runOnUpdateCallback(props); } - componentWillReceiveProps(nextProps) { - this.runOnUpdateCallback(nextProps); + componentDidUpdate(nextProps) { + this.runOnUpdateCallback(this.props, nextProps); } - runOnUpdateCallback = props => { + runOnUpdateCallback = (props, nextProps = {}) => { const { currentRoute, client } = props; // the first argument is an item to iterate on, needed by vulcan:lib/callbacks // note: this item is not used in this specific callback: router.onUpdate runCallbacks('router.onUpdate', {}, currentRoute, client.store, client); + + runCallbacksAsync('router.onUpdate.async', props, nextProps); }; render() { diff --git a/packages/vulcan-events/lib/modules/events.js b/packages/vulcan-events/lib/modules/events.js index dadfcb923..5d435e6ae 100644 --- a/packages/vulcan-events/lib/modules/events.js +++ b/packages/vulcan-events/lib/modules/events.js @@ -37,7 +37,7 @@ export const addIdentifyFunction = f => { }; export const addPageFunction = f => { - const f2 = (empty, route) => f(route); + const f2 = ({ currentRoute }) => f(currentRoute); // rename f2 to same name as f // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty @@ -45,5 +45,5 @@ export const addPageFunction = f => { descriptor.value = f.name; Object.defineProperty(f2, 'name', descriptor); - addCallback('router.onUpdate', f2); + addCallback('router.onUpdate.async', f2); }; diff --git a/packages/vulcan-lib/lib/modules/callbacks.js b/packages/vulcan-lib/lib/modules/callbacks.js index 1b128a151..265f5843f 100644 --- a/packages/vulcan-lib/lib/modules/callbacks.js +++ b/packages/vulcan-lib/lib/modules/callbacks.js @@ -1,3 +1,5 @@ +import { Meteor } from 'meteor/meteor'; + import { debug } from './debug.js'; import { Utils } from './utils'; @@ -169,17 +171,24 @@ export const runCallbacksAsync = function () { const callbacks = Array.isArray(hook) ? hook : Callbacks[hook]; - if (Meteor.isServer && typeof callbacks !== 'undefined' && !!callbacks.length) { + if (typeof callbacks !== 'undefined' && !!callbacks.length) { + const _runCallbacksAsync = () => + Promise.all( + callbacks.map(callback => { + debug(`\x1b[32m>> Running async callback [${callback.name}] on hook [${hook}]\x1b[0m`); + return callback.apply(this, args); + }), + ); - // use defer to avoid holding up client - Meteor.defer(function () { - // run all post submit server callbacks on post object successively - callbacks.forEach(function (callback) { - debug(`\x1b[32m>> Running async callback [${callback.name}] on hook [${hook}]\x1b[0m`); - callback.apply(this, args); + if (Meteor.isServer) { + // TODO: find out if we can safely use promises on the server, too - https://github.com/VulcanJS/Vulcan/pull/2065 + return new Promise(async (resolve, reject) => { + Meteor.defer(function() { + _runCallbacksAsync().then(resolve).catch(reject); + }); }); - }); - + } + return _runCallbacksAsync(); } - -}; \ No newline at end of file + return []; +};