We love open source software here at CrowdSync.
Sometimes though, we run into issues with the software we’ve deemed as the
“right” package for us.
A recent incident has been with React Draft Wysiwyg which we decided to
use as part of our action to compose and send emails to people in your workflow.
If you’re not familiar with the package, it’s a WYSIWYG editor that is built on
top of Draft.js (which is built on top of React).
It’s arguably one of the most popular editors available that’s built on top of
Draft.js which made it the obvious choice for us.
Getting the editor wired up and working and saving to MongoDB didn’t take much
effort at all. Where we got hung up was on recalling the information and
presenting it back to the user correctly.
Between the two of us, we went through storing the EditorState
and the
ContentState
in a bunch of ways. Converting back and forth between Draft.js’s
raw format and anything else we could think of to try to get things to work.
After already spending a night trying to figure things out, I decided the next
night that I wasn’t going to go to bed until things were resolved.
After fighting with things for a bit, I decided to compare what the object
looked like as it went into MongoDB and how it looked coming out.
To my surprise, a bunch of crap was missing from the object. Specifically, all
of the empty object properties were not present.
After some research and filed in the TIL category, seems that MongoDB doesn’t
store empty data to conserve space.
Makes sense to me, but was also munging the crap out of my data and making it
unusable once recalled from MongoDB.
To get around the issue, I opted to use JSON.stringify()
and JSON.parse()
on
the raw content object. Not the most elegant solution but it allowed us to store
the object versus converting things to HTML and storing that.
We really wanted the flexibility of storing the object in case we want to do
other things with it in the future, like exporting it as Markdown or whatever.
So how’s the code look? Going into MongoDB looks something like this:
import { convertToRaw } from 'draft-js'
import { editorState } = this.state
const rawState = JSON.stringify(convertToRaw(editorState.getCurrentContent()));
Then when we pull the data out of MongoDB:
import { convertFromRaw, EditorState } from 'draft-js'
this.state.editorState = EditorState.createWithContent(
convertFromRaw(JSON.parse(this.props.rawState))
Frustrating at the time but the solution was pretty simple albeit not the most
elegant as we’re juggling through multiple formats.
With that, it’s working for us so, NEXT ISSUE!