[Solved] How to save editorState Data from DraftJS in Meteor

I’d like to organize a conversation around the topic of what is the best way to accomplish this task. Using React’s DraftJS as a rich text editor - what do you all think is the best way to save data in a Meteor collection.

Let’s say I have a page with text on it which I as the admin will author using DraftJS. Once published, regular users will be able to see this page of “rich text” as regular HTML code. At any time as the admin, I’d like to be able to edit the text on this page again with DraftJS and “save” it back to the meteor collection.

What is the best way to “store” the rich text in the meteor collection?

As HTML? (isn’t that dangerous?)
As a “raw javascript object” given to me by DraftJS? (isn’t that too complex for mongo to handle efficiently?)

Any thoughts on the matter?

Is anyone already doing this - if so, how? Do you have a demonstration or code you can point us to?

Right now the best way I have come up with myself is to “convert” the DraftJS editorState to raw HTML and then store that in the collection to be “output” again. The only problem I have with this is how to avoid having unwanted HTML injected into the site.

If this is the only way - is there any way to “sanitize” the HTML so that it’s safe?

Any other pointers for this method?

Is there a better way?

Here is a project where most of the ground work is already laid out.

Using DraftJS, React, Meteor even loading state from Raw HTML. I don’t have any collection to save the HTML into yet. I wasn’t sure how I was going to go about that next. Everything is ready to go. I’m just unsure what the “best practice” would be for storing this information.

When do I convert the editorState to HTML? Before, or after I store it in the collection? And why?

Side Note: I’m using Material-UI in this project also - those guys made some very fine code indeed.

1 Like

You can save the editorState like this:


const content = DraftJS.convertToRaw(editorState.getCurrentContent();
// save it in a collection
Pages.update(pageId, { $set: { content } })

and the other way around:


const { content } = Pages.findOne(pageId);

const draftContent =DraftJS.convertFromRaw(content);
const editorState = EditorState.createWithContent(draftContent);

2 Likes

Why should it be difficult for MongoDB to handle? You just save and retrieve a field with the raw json, you are not doing any editing of the raw object in the DB.
Converting to HTML will remove the advantages of using DraftJS.

There is a concern with DraftJS that it becomes sluggish as the size of the document grows. When I was researching DraftJS, I came across such an article. Having said that, I still chose DraftJS for my project.

Thank you very much for your post!

This only leaves me with one last question: How would you suggest handling the output for when a “regular user” is viewing the page (without rights to edit the document)? Would you just output the HTML using react’s dangerouslySetInnerHTML? and the harder question: Would doing so make the site vulnerable to a cross-site scripting attack (XSS)?

Generally speaking, I don’t like to use dangerouslySetInnerHTML because I don’t understand XSS deeply enough and I always try to find some way around this.

… While writing this post it looks like I answered my own question. It looks like I can just use DraftJS’s readOnly prop for the Editor. Any advice against this? Cause it looks like this is what I’m going to use. Using this renders links clickable etc.

This looks like the best option.

Thanks for all the help everyone.

If you’re going to render user-inputted raw html, you should probably use something like https://github.com/punkave/sanitize-html:

const content = sanitizeHtml(DraftJS.convertToRaw(editorState.getCurrentContent());
// save it in a collection
Pages.update(pageId, { $set: { content } })
1 Like

This is an excellent resource! Thank you so much!

yes, you can use draftjs to display it as well. e.g. we use drafjs with https://github.com/globocom/megadraft in a project. You can even create nice inline-editing. Only problem is, that it creates a bigger dom-tree than needed, but you know: performance last.

@babrahams, @marktrang
Great info in this post … Now with all your help I am able to store data in mongo and also bale to extract it, problem is when I try to edit it, instead of editing particular line where my cursor is, it goes to the beginning of the content and insert data there

What should I do?

Could you upload what you’ve got to a github repository and send a link?

This was very straightforward for me - I basically just set it up as a “controlled” input with React and stored the state “onChange”. I save it to the database on every keystroke (probably not the best, but it works for my application).