Upgrading from Dojo to React

Mendix Community
Published in
8 min readApr 12, 2021

--

Over the last 7 years I have been building many Mendix applications for just as many clients. One of the expertises I gained is in the field of extending the Mendix platform with GIS functionality using for instance Google Maps or ArcGIS. For both platforms I have published several components in the Mendix Marketplace, like the one I am writing this blog about, Google Maps Polygon.

These more complex widgets have all been built on top of the Mendix Dojo JavaScript framework. I have been working with the Dojo framework just as long as I have been building Mendix apps, so moving to React was something new for me.

Mendix is in the process of moving their main JavaScript front-end framework from Dojo to React, mainly because the React framework is more futureproof. It does mean, however, that all widgets currently built in the Dojo framework will eventually stop working if the usage of the Dojo framework is really phased out. So, eventually all these widgets will need to have a React counterpart.

In this blog I want to share my takeaways on moving from Dojo to React, hoping it will help other developers on their tasks of upgrading their marketplace content. The main takeaways, handled one by one below, are:

  • Choose correct React library!
  • Let React do the rendering!
  • Take full advantage of Pluggable Widgets API
  • Create components for heavily used objects
  • Choose carefully what is stored in state of each component

1. Choose the correct React library

Once the widget is set up via the Mendix widget boilerplate, as explained in other blogs, like this one, the first thing that needs to be done is importing the right React libraries. Next to importing the correct node modules, the typings needed to be loaded as well. It is key to choose the correct library. In my case I wanted to integrate with the Google Maps API. I quickly found out that there are already many React libraries out there. After looking into the three top ones:

  • React Google Map
  • Google Map React
  • Google Maps React

I chose the last one, and actually even an extension thereof https://www.npmjs.com/package/@react-google-maps/api

There are three reasons for choosing this library:

  1. The library actually supports Polygons as React components, whereas for instance React Google Map doesn’t
  2. The library is maintained quite well, see the active status on GitHub
  3. Mendix also chose this library for the new Map widget
https://bit.ly/MXW21
https://bit.ly/MXW21

2. Let React do the rendering!

At first I chose to pick another library, Google Map React, because that is the library the first Mendix Maps widget was built in. After adding the modules and the first components, I found out that the Polygon component was not fully implemented with that React library as I should have known by properly reading the documentation of the React library:

google-map-react is a component written over a small set of the Google Maps API. It allows you to render any React component on the Google Map.

Especally the part ‘small set’ turned out to be very important and resulted in quite some waste time from my side. I tried to create the Polygon object as a React component myself which I achieved, but then I also had to add InfoWindow objects. An InfoWindow is an actual pop-up that can be shown when clicking on the map itself or an object on the map. Since for the widget I needed to add a button that can trigger an action (show page/run microflow etc) I needed a bit more complex HTML to be shown in the info window. I tried in several ways to add the HTML (not being a React component itself) to the infowindow via the React library ReactDOMServer, but all my efforts failed and left me a bit frustrated with how hard it is to add HTML to a component build in React. After reading up on struggles from other developers on ‘Stack Overflow’ and other websites I came to the conclusion that I should not try to use ReactDOMServer unless all other options fail. So, I switched to another library supporting Polygons and InfoWindows as actual React components.

3. Take full advantage of Pluggable Widgets API

There are four huge benefits I found when working with the new Pluggable Widgets API, so switch if possible! When writing widgets in the older Client API written for the Dojo framework, the first three functionalities would typically take a huge chunk of development time and are not easy to build.

  1. All types of data source are supported
  2. All types of action are supported
  3. Editability/Visibility can be inherited
  4. Group widget settings together

1. All types of data source are supported

By in the XML of the widget adding an element of type datasource

Widget XML: type=”datasource”

a developer will be able to select all different types of datasource in the widget settings:

New API supports all data sources out-of-the-box

2. All types of action are supported

Another standard requirement is being able to trigger actions from inside the widget. In the Google Maps Polygon widget for instance it should be possible to trigger a microflow from clicking on a Polygon or Polyline. With the new Pluggable Widgets API this is very easy now. Just add in the widget XML a type=”action”:

Widget XML:Type=”action”

So the developer can select any supported action in the widget settings:

New API exposes all actions out-of-the-box

In the JavaScript only one statement is needed to trigger this action:

3. Editability/Visibility can be inherited

The new Pluggable Widgets API exposes new system properties also available for other Mendix default widgets:

  • Visibility
  • Editability

Add them, again, via a newly available setting in the widget XML:

Widget XML system properties

4. Group widget settings together

It is now possible to add an extra nested propertyGroup in an existing properyGroup within the widget XML. The first propertyGroup will generate a tab in the widget settings, the nested property group will add a groupbox in the specific tab, very usefull for readability:

Wdget XML: Nested property groups

Above setting will result in below widget settings:

Studio Pro: nested property groups

4. Create components for heavily used objects

Stating the obvious, when building a more complex widget based on React it is best practice to create components out of the most heavily used objects. For the Google Maps Polygon widget I created separate components for the Polygon, Polyline, Marker and Info Window objects.

In the Dojo framework this was also already a best practice, grouping specific functions in separate JavaScript files, but when using Visual Studio Code and the new React framework with import statements this is so much easier than in the Dojo framework. This was the reason why I sometimes caught myself putting all JS code in one file in the Dojo framework…

5. Choose carefully what is stored in state of each component

When needing to support multiple children for your main React component, in my case Polygons, Polylines and InfoWindows, it is key to properly choose what to store in the state of each component. An example: the InfoWindow component should become visible when clicking on a Polygon or Polyline and showing the information of that object. Hence, I was hoping and actually expecting the React library would have a parent - child relation for the components in this order:

Map > Polygon / Polyline > InfoWindow

Sadly, the library had an InfoWindow as a direct child on the Map itself, so:

Map > Polygon / Polyline / InfoWindow

Hence making sure an InfoWindow is shown when clicking on a Polygon or Polyline should be handled via the Map component itself..

To achieve this I added a couple of things:

  • Added a setting to the state of the Map component: showingInfoWindow
  • Adding an object to the state of the Map component: infoWindowObj, containing the name, position and corresponding Mendix Object (needed for being able to trigger an action via the InfoWindow)
  • Set showingInfoWindow to false on first render of Map Component
  • In the render of the Map component, only show the InfoWindow on the position if showingInfoWindow is set to true
  • Added a generic handler in the Map component for the on click of child polygon and polyline objects, which sets showingInfoWindow to true and updates the name, position and associated Mendix Object of the infowindow.
  • Add a handler on the InfoWindow component to set the showingInfoWindow back to false when closing the InfoWindow.

Since we are changing the state of the parent, the render function will be triggered every time an info window is shown by clicking on an object or closed. To make sure not all objects (including kicking off of data source) are reloaded again, you should keep track of whether the objects are already shown as well. This can be done in the Polygon / Polyline shouldComponentUpdate function, to prevent the object from rerendering if all data (props) are still the same.

Conclusion

Even though my understanding of JavaScript and the Dojo framework was already quite high, it turned out to take quite some time to rewrite this complex widget. I lost some hours on investing in the wrong React library and creating the workaround for the InfoWindow not being a child of the Polygon / Polyline. I am very pleased with the end result, as it is working well and now supports all data sources and actions Mendix provides out-of-the-box. I hope this blog will give other developers some more understanding of the pro’s and con’s of moving from Dojo to React.

End result

Today I have published the new React based version of the Google Maps Polygon widget to the Mendix Marketplace. You can download it here. Feel free to check out the code on GitHub as well!

Read more

From the Publisher -

If you enjoyed this article you can find more like it at our Medium page or at our own Community blog site.

For the makers looking to get started, you can sign up for a free account, and get instant access to learning with our Academy.

Interested in getting more involved with our community? You can join us in our Slack community channel or for those who want to be more involved, look into joining one of our Meet ups.

--

--