Closed maxtacco closed 6 years ago
Also, this may require GrapesJS' init method to return a Promise instead of the editor, but this can be limited only to cases when there are any plugins that return Promises.
I have to set 'editor.autorender' to false and then render editor manually once my plugin is initialized. This is fine for now, but I'm not quite sure how I would handle this case if I had multiple custom plugins depending on some async logic
Just use a variable as a flag which counts your custom execution logic and once it's finished you're ready to render it. IMHO, the solution with Promises it's absolutely overwhelmed for such a thing
Yes, I can probably make it work but it is going to be kinda hacky.
I had a similar requirement. If it helps others, my solution in the end was to create a plugin which then loads my other plugins;
The editor config would just reference the one plugin and the plugin options for that plugin would contain the plugins and options for the others to load.
The plugin code;
export default grapesjs.plugins.add("async-plugins", async (editor, opts) => {
/**
* opts = {
* plugins: [ ... ]
* pluginsOpts: { ... },
* render: true | false, // If not set this will default to true.
* onFinished: async (editor) => {
* // When the async plugin has finished.
* },
* };
*
* If using the 'render' here, make sure to set 'autorender' to false in the editor config.
*/
// Load the specified plugins.
for (let i = 0, len = opts.plugins.length; i < len; i++) {
const pluginId = opts.plugins[i];
if (!opts.pluginsOpts) {
opts.pluginsOpts = {};
}
// Attempt to get the plugin if it has been registered.
let plugin = grapesjs.plugins.get(pluginId);
if (!plugin) {
const wplg = window[pluginId];
plugin = wplg && wplg.default ? wplg.default : wplg;
}
// Attempt to execute the plugin using 'await'.
if (plugin) {
await plugin(editor, opts.pluginsOpts[pluginId] || {});
}
else if (pluginId instanceof Function) {
await pluginId(editor, {});
}
else {
console.warn(`Failed to load plugin ${pluginId}.`);
}
}
// Render the editor if this plugin has been configured to do so.
if (opts.render === undefined || opts.render === true) {
editor.render();
}
// If there is an 'onFinished' callback, call it.
if (opts.onFinished) {
await opts.onFinished(editor);
}
});
The editor init code;
grapesjs.init({
...
autorender: false,
plugins: [ 'async-plugins' ],
pluginsOpts: {
'async-plugins': {
plugins: [ ... ],
pluginsOpts: { ... },
render: true,
onFinished: async (editor) => {
console.log("FINISHED");
},
},
},
...
});
Hi @artf, I have a case where a custom plugin needs to check user permissions before doing any kind of initialization. The method that does the check returns a Promise, so I have to wait for it to resolve before doing anything. Unfortunately, this creates a raise condition with editor rendering and UI gets into some weird state. In order to solve this issue I have to set 'editor.autorender' to false and then render editor manually once my plugin is initialized. This is fine for now, but I'm not quite sure how I would handle this case if I had multiple custom plugins depending on some async logic.
So, it would be really nice if GrapesJS could check if any of the registered plugins return Promises and only render the editor when all of them are resolved.
Thank you for you awesome project.