<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Raul-Sebastian Mihăilă</title>
    <description>The latest articles on DEV Community by Raul-Sebastian Mihăilă (@raulsebastianmihaila).</description>
    <link>https://dev.to/raulsebastianmihaila</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F308485%2F97095ec2-a5f6-4370-9f59-83a6f777317a.jpeg</url>
      <title>DEV Community: Raul-Sebastian Mihăilă</title>
      <link>https://dev.to/raulsebastianmihaila</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/raulsebastianmihaila"/>
    <language>en</language>
    <item>
      <title>Implementation examples of common front-end features in complex applications</title>
      <dc:creator>Raul-Sebastian Mihăilă</dc:creator>
      <pubDate>Wed, 08 Jul 2020 18:20:32 +0000</pubDate>
      <link>https://dev.to/raulsebastianmihaila/implementation-examples-of-common-front-end-features-in-complex-applications-6hh</link>
      <guid>https://dev.to/raulsebastianmihaila/implementation-examples-of-common-front-end-features-in-complex-applications-6hh</guid>
      <description>&lt;p&gt;&lt;a href="https://raulsebastianmihaila.github.io/crizmas-mvc-examples/"&gt;Here are exemplary implementations of different features&lt;/a&gt; that we often run into when developing a complex application.&lt;/p&gt;

&lt;p&gt;We focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handling async state&lt;/li&gt;
&lt;li&gt;Complex form validation&lt;/li&gt;
&lt;li&gt;Handling application contexts&lt;/li&gt;
&lt;li&gt;Wizards&lt;/li&gt;
&lt;li&gt;Scroll virtualization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling async state
&lt;/h2&gt;

&lt;p&gt;Big applications typically involve communicating with servers and sometimes rich UIs need to reflect the pending state of multiple parallel async operations. We can employ a mechanism that reflects if a certain operation or a group of operations are pending. This exempts us from the tedious job of handling the state of each operation. This state can also be seen as a hierarchy: we can disable a button while its associated operation is in progress or we can block an entire area of the screen if it contains one or more UI elements with pending operations associated.&lt;/p&gt;

&lt;p&gt;Cancelling async operations is also useful, especially when a certain context of the application is left and the results of the operations are not needed any longer. The capability of grouping operations is especially important, such that they can be cancelled together when needed.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Complex form validation
&lt;/h2&gt;

&lt;p&gt;The input data may be temporary data that is created on the spot or the form can reflect existing model data that could also be invalid from the beginning. We may want to validate a certain input when another input is changed, for instance an input that represents an end date could become invalid if the input that represents a start date is updated and the start date is now greater than the end date.&lt;/p&gt;

&lt;p&gt;We may need to validate inputs asynchronously and for a good UX we would want to allow interlaid async validations. We described our approach extensively in &lt;a href="https://medium.com/@raul.mihaila/crizmas-status-update-and-the-form-interlaid-asynchronous-validations-4abf167a54bb"&gt;a previous article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Gathering data representing big and complex entities is done often through a wizard. The entire flow must represent a single form as a whole. For more details, check the wizards section.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling application contexts
&lt;/h2&gt;

&lt;p&gt;If completing an operation that the user started is very important, or if the user spent a long time working on something in a context of the application, leaving that context by mistake should be prevented until the user confirms that leaving is desired.&lt;/p&gt;

&lt;p&gt;There are also cases where entering a context of the application should be prevented, for instance if we have a wizard where each step is a separate route, and we want to enforce a certain order of visiting the wizard steps, in case the user tries to enter a step that shouldn't yet be available, we could redirect them to the right step that needs to be completed before. See the wizards section for details.&lt;/p&gt;

&lt;p&gt;Every once in a while, when certain steps are finished we want to bring the application to a state that is similar to the beginning of the flow that the user has just completed. In other words we would want to mimic the user's re-entrance in the current flow of the application. An elegant way of implementing this is by refreshing the current route, meaning the current route or routes (if we have a hierarchy of nested routes) are left one by one from the end to the start and reentered from the start to the end, calling any entrance or exit route guards. Or, even more interesting, we may want to refresh only a part of the hierarchy of routes. This is the best handled by a routing library.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wizards
&lt;/h2&gt;

&lt;p&gt;Let's imagine we need to implement a wizard in which each step is a route. In order to get to the next step by using the &lt;code&gt;next&lt;/code&gt; button you have to complete the current step. If a step contains a form, in order to be completed, the form needs to be submitted successfully. If a step doesn't contain a form, the step is completed by simply being visited. You can not jump to a step, by using the step number links, without completing the previous steps, unless the step you're jumping to has already been visited. This allows us to complete a step with a form, visit the next step, go back to the previous step that contains the form, make a change such that the form becomes invalid and jump to the next step without fixing the form. However, on the last page when we hit submit, if there are any steps that have an invalid form we jump to the first one in that category. If we try to access a certain step by transitioning programmatically to that step, if that step hasn't been visited before, we're redirected automatically to the first step that has never been completed. The step number links at the top of the wizard are active only for the steps that have been visited. All the step forms are composed into one single form with which we gather all the data when submitting the wizard data on the last step. As we navigate through the wizard we don't want the state of each step to be lost. However, once we leave the wizard altogether, we want its state to be lost. We also want this wizard mechanism to be reusable for other contexts of the application and be able to focus only on implementing each step of the wizard and on putting the pieces together.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Scroll virtualization
&lt;/h2&gt;

&lt;p&gt;Enterprise applications may contain lots of data and in certain cases you may want to display tables with many entries. Or you may want to display a large grid. This can have a performance impact if we want to render many elements, therefore we may choose to implement scroll virtualization, so that we can display a big list of items without blocking the browser. More precisely, only a part of the items are rendered while for the user it appears that all the items are rendered.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Ideally all the frameworks should make these easy for us to implement so that we can focus instead on the business requirements. Other than what we mentioned, complex applications may also contain capable components such as tables with different features or charts or other capabilities that separate libraries may provide, such as viewing a PDF. What other similar features did you run into that we didn't cover?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>complexity</category>
      <category>ergonomics</category>
    </item>
    <item>
      <title>Natural cure game with Javascript and HTML5</title>
      <dc:creator>Raul-Sebastian Mihăilă</dc:creator>
      <pubDate>Sun, 17 May 2020 09:33:00 +0000</pubDate>
      <link>https://dev.to/raulsebastianmihaila/natural-cure-game-with-javascript-and-html5-3fb5</link>
      <guid>https://dev.to/raulsebastianmihaila/natural-cure-game-with-javascript-and-html5-3fb5</guid>
      <description>&lt;p&gt;I've recently published a game called &lt;a href="http://natural-cure-game.web.app/"&gt;Natural cure&lt;/a&gt;. It's a game about viruses, vaccination and shootings. It should be played on a big screen (not on mobile phones), in order to be able to move around. You also need to do a lot of right-cliking. It seems to be working the best in Chrome. It's hosted with Firebase. I made it from scratch, meaning I didn't use any library for building games, just Javascript, HTML and CSS. I did, however, use the crizmas-mvc framework (based on React) for the menus, popups etc. The most challenging part was getting the path finding algorithms right, including the optimizations. I started it a few years ago, took big breaks and it was never clear that I was going to finish it because I've never had an idea of a game story. Given the current COVID-19 situation, I thought of killing my time more efficiently updating the game. The result is quite interesting. Another thing I focused on was code obfuscation. In particular, I focused on mangling the property names of objects so that the code is even more difficult to read than only with minifying the code. Therefore, the intention is not to share the code with you, but, if you'd like a challenge, try to see if you can get an idea of how the code works and what its structure is.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>game</category>
      <category>naturalcure</category>
    </item>
    <item>
      <title>Prototypal noninheritance in Javascript</title>
      <dc:creator>Raul-Sebastian Mihăilă</dc:creator>
      <pubDate>Mon, 06 Jan 2020 06:25:43 +0000</pubDate>
      <link>https://dev.to/raulsebastianmihaila/prototypal-noninheritance-in-javascript-b8f</link>
      <guid>https://dev.to/raulsebastianmihaila/prototypal-noninheritance-in-javascript-b8f</guid>
      <description>&lt;p&gt;Everybody knows that the inheritance mechanism in Javascript is prototypal. Many also know that it's possible for an object to not have a prototype and therefore not inherit anything. But did you know that it's possible for an object to have a prototype but not inherit from it?&lt;/p&gt;

&lt;p&gt;First of all, while the Javascript specification provides hints about what inheritance is, it doesn't fully define it. But how can we observe the inheritance mechanism? Well, we need an object with a prototype, see that the object doesn't have a property that the prototype has and then when we access that property on the object we get the same value that we would get if we accessed it on the prototype. We're also freezing the object and the prototype in order to make things look less dynamic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setPrototypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPrototypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// proto&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPrototypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So basically we made eight observations here and we're looking to prove that it's possible for the last two observations to be different for a particular object, even if the first six are the same as in this example.&lt;/p&gt;

&lt;p&gt;The answer is: proxies!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyTarget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setPrototypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPrototypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// proto&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPrototypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>inheritance</category>
      <category>proxy</category>
      <category>prototype</category>
    </item>
    <item>
      <title>The React based crizmas-mvc front-end framework for enterprise applications</title>
      <dc:creator>Raul-Sebastian Mihăilă</dc:creator>
      <pubDate>Sat, 04 Jan 2020 20:32:33 +0000</pubDate>
      <link>https://dev.to/raulsebastianmihaila/the-react-based-crizmas-mvc-front-end-framework-for-enterprise-applications-5aod</link>
      <guid>https://dev.to/raulsebastianmihaila/the-react-based-crizmas-mvc-front-end-framework-for-enterprise-applications-5aod</guid>
      <description>&lt;p&gt;Hi guys! Just wanted to share with you this article where I describe the crizmas-mvc framework based on React, in what way it's better than other frameworks and why you should use it. :-)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@raul.mihaila/the-crizmas-mvc-front-end-framework-for-enterprise-applications-d89d9f2fe281"&gt;https://medium.com/@raul.mihaila/the-crizmas-mvc-front-end-framework-for-enterprise-applications-d89d9f2fe281&lt;/a&gt;&lt;/p&gt;

</description>
      <category>crizmasmvc</category>
      <category>react</category>
      <category>frontend</category>
      <category>framework</category>
    </item>
    <item>
      <title>The crizmas-mvc front-end framework for enterprise applications</title>
      <dc:creator>Raul-Sebastian Mihăilă</dc:creator>
      <pubDate>Sat, 04 Jan 2020 19:59:38 +0000</pubDate>
      <link>https://dev.to/raulsebastianmihaila/the-crizmas-mvc-front-end-framework-for-enterprise-applications-hjd</link>
      <guid>https://dev.to/raulsebastianmihaila/the-crizmas-mvc-front-end-framework-for-enterprise-applications-hjd</guid>
      <description>&lt;h3&gt;
  
  
  Contents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Intro&lt;/li&gt;
&lt;li&gt;What to expect from a framework&lt;/li&gt;
&lt;li&gt;Main ideas&lt;/li&gt;
&lt;li&gt;Why and when it's good&lt;/li&gt;
&lt;li&gt;Compared to other frameworks/approaches&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;There are a few good Javascript front-end frameworks (and we’re using the word ‘framework’ in the more general sense, in which even a group of libraries that work together can form a framework). But are they good enough? We can’t talk about a perfect framework. It all boils down to how capable the framework is (in relation to the goal) and how comfortable you are with it. And there are quite a few aspects to take into account. This new framework (although 3 years old) is our take on how things can be done better. In this article we try to explain why and how crizmas-mvc is a very well suited framework for complex enterprise applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to expect from a framework
&lt;/h3&gt;

&lt;p&gt;The main characteristic that a framework must have is being capable. It must be easy to build with it all the common features that we’re used to seeing in a UI. The framework must allow you to focus on the business requirements and on the more special features that the framework itself couldn’t account for, instead of making you scratch your head when you run into situations where it gets really weird to implement a rather common requirement.&lt;/p&gt;

&lt;p&gt;The next characteristic to look for is flexibility. A framework may appear to be very capable because it may seem you can build with it most of what you can think of, but then in practice you might have to implement a rather awkward UX behavior. Or you might need to integrate with some third party component or library that doesn’t really fit the general approach that the framework is enforcing. Or the business requirements might have you wonder why you would have to implement something like that. The point is that many times you have to implement things that you would rather avoid implementing, but still have to implement them, and perhaps the framework wasn’t build to cater for those situations. Therefore a framework should allow you to employ different approaches and patterns.&lt;/p&gt;

&lt;p&gt;It’s also very important for the framework to be free of errors. Sometimes you read the docs of a framework or library and it turns out it’s not doing what it was supposed to. Tightly related to this is the rapid development of the framework. If you need to wait a long time for a fix you will end up doing workarounds.&lt;/p&gt;

&lt;p&gt;For corporations it’s often important for the framework to be popular. This allows them to hire new people that are already familiar with the framework. Also for developers it’s important because they get more job opportunities. However there should be room for new approaches as well, otherwise the progress is hindered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main ideas
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Independent model
&lt;/h4&gt;

&lt;p&gt;There are simple applications for which pretty much any framework will do and there are more complex applications, for instance what one would typically call enterprise applications, where structure, conventions and ceremonies are essential. Certain frameworks enforce a quite rigid structure and you pretty quickly find yourself making a face at this when it feels abnormal. When it comes to structure there is always a part of the codebase that can be understood independently from the framework because, at least in theory, you would normally want to implement it similarly using any other framework as well. This is what usually a domain model looks like. Understanding and expressing well the domain model is very important since that is the essence of the application and cutting corners or resorting to workarounds makes developers uneasy because that makes the model more difficult to understand. This is the first idea of crizmas-mvc. The model can be written in absolutely any way you want. The framework doesn’t provide anything for you to write the model. It doesn’t need to bind to anything, it doesn’t need to be decorated with anything and you don’t need to use any API for defining the model. Some frameworks are more appropriate for a specific way of organizing the code. However, typically a complex application requires multiple ways of organizing the code and the flexibility and the missing rigidity are the best approach.&lt;/p&gt;

&lt;p&gt;One positive consequence of this is that you don’t depend on the framework to support certain data structures. For instance, a reactive system (for instance Vue’s) might transform your data and if the data structure has a special behavior (for instance it accesses some private internal data) the framework needs to wrap or transform that data structure in a specific way. Whenever such a new data structure is added to the programming language, the framework needs to be updated. This evidently has some limitations, you’re restricted to comply with the rules and for instance you can’t simply define your own objects with such a special behavior and use them any way you want. Or if you have to use a third party library that isn’t tailored for that framework, you need to work on adapting it for the framework and this can be a challenge.&lt;/p&gt;

&lt;p&gt;The essential benefit of model independence is that you fully understand what it does as long as you understand the programming language and your own code. Frameworks may have a subtle way of implementing reactivity and sometimes you scratch your head because it’s not intuitive why your view is not being updated when you change some state. This may be a combination of subtle framework mechanics and rigidity.&lt;/p&gt;

&lt;p&gt;Frameworks may transform your data in order to implement the reactivity (or the binding mechanism between the view and the data) and also for performance optimizations for efficient view updates. However, this transformation may be costly if the data is bigger.&lt;/p&gt;

&lt;h4&gt;
  
  
  Managing the pending state for trees of objects
&lt;/h4&gt;

&lt;p&gt;One common thing that applications do is representing the pending state of the application. Data may be loading or operations may be in progress and you may want to show a spinner or disable particular buttons depending on the pending state of certain operations. You may also be interested in combinations of pending operations, depending on how complex the UI is. It’s therefore important to structure the pending state. Given the way crizmas-mvc manages the controllers you automatically get this pending state management with which you can easily tell which operation is in progress. You can also see if a group of operations are in progress as the controller is pending while it has any pending operations associated with it. The icing on the cake is that you can have a tree of pending objects, where a parent object is pending if it has at least one pending operation associated with it or if it has any child objects that are pending.&lt;/p&gt;

&lt;p&gt;It’s quite surprising that most frameworks don’t handle this as easily, since it’s a very common feature we see in applications. Not all frameworks support all the common features as easily, even though they claim they facilitate building very complex UIs.&lt;/p&gt;

&lt;h4&gt;
  
  
  Controllers
&lt;/h4&gt;

&lt;p&gt;There’s this hype around components going on. Components in general are very important for modularity and in this respect we have to consider all kinds of components, not only view components. However, the hype is mostly around rendered components. Some of them can be more than view components, for instance the Flux architecture introduces the notion of controller-view. View components specifically are very important for structuring the view layer and they are typically used as part of a composite pattern. But the most popular frameworks today give a greater responsibility to these components. There is an evident tendency to compose as much of your application as possible with such components. This means a lot more is put into the view layer. The components can do more than displaying things. For instance, they may have controller logic, they may hold data and state that could be kept somewhere else. You can also have components with the purpose of reusing some sort of functionality they implement, but without rendering anything but their children. You may therefore end up with having a tree of components each with different fundamental responsibilities, which can be seen as a departure in spirit from the composite pattern, as the uniformity is given only by the rendering aspect, but less by what the layer is concerned with.&lt;/p&gt;

&lt;p&gt;Keeping the components in the same tree means they participate in the same lifecycle. While for rendering (and the composite aspect of it) this makes a lot of sense, it becomes troublesome when the components have other responsibilities, such as keeping state or performing operations such as data fetching. Flux itself recommends to keep controller-views at the top of the tree. A good example are tabs. If your components are contained in tabs, when the user switches tabs, assuming that only the active tab renders its content, the components from the other tabs are unmounted and whatever state they might be holding is lost. Controllers in crizmas-mvc can hold such state that is used by the components and since the controllers are not held in the state of the components we work out this deficiency that components with state have. In short, controllers are independent from the view lifecycle. But controllers are even more important than this.&lt;/p&gt;

&lt;p&gt;With Flux (or other approaches inspired by it), in order to solve the component state issue, we can either move the state higher in the tree of components or move the state to the store. Keeping the state in the parent component can bloat it. Moving the state in the store can have some unfortunate consequences such as mixing domain model state with view or controller state. Normally the store module (with Vuex, or a Redux reducer used with the &lt;em&gt;combineReducers&lt;/em&gt; API) requires clearing when the context where that module is relevant is left by the user. Controllers allow us to instantiate models in the controllers themselves and if we keep them locally in the controllers, when the controllers are not used anymore that model state is lost automatically and doesn’t need clearing.&lt;/p&gt;

&lt;p&gt;In crizmas-mvc there is a clearer separation between the view, the controller and the domain model, with regard to their logic and state. For instance, with Redux and Vuex the controller logic can stay in many places and it can also be mixed with the data handling in the store. There we have controller-views, middlewares, actions and action creators and reducers or mutations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Router capabilities
&lt;/h4&gt;

&lt;p&gt;Beside the capabilities that a typical router provides, such as matching paths with parameters, fallback routes, regexp matching, redirects, entering and leaving hooks that can be used for implementing guards etc., crizmas-router provides some more fancy capabilities as well.&lt;/p&gt;

&lt;p&gt;Refreshing the current route is a very requested feature from all the most popular frameworks. The nicest feature of crizmas-router, one that we couldn’t find in any other framework, is being able to refresh the current path from any fragment. This means that if we have a hierarchy of route fragments that are handling the current path of the application (each URL path fragment having a separate route fragment associated with it), we can refresh only a part of them or all of them (meaning that they will be left and re-entered).&lt;/p&gt;

&lt;p&gt;We can’t really speak about a modern framework anymore today if it doesn’t support lazy loading. All the most popular frameworks support this and crizmas-router does too.&lt;/p&gt;

&lt;p&gt;By working with a very easy to use API, routes can be dynamically checked, added, removed and listed at any point in time and crizmas-router also provides a nice option for case insensitivity at the router level or at the route level.&lt;/p&gt;

&lt;h4&gt;
  
  
  Form capabilities
&lt;/h4&gt;

&lt;p&gt;crizmas-form provides event based sync and async validations. The validations are triggered when standard events occur, but they can also be triggered with custom events. The validation event always has a target associated with it, which allows us to validate related fields when a certain field is interacted with. The inputs typically form a tree of inputs and we can have lists of inputs too.&lt;/p&gt;

&lt;p&gt;Sometimes the form data represents temporary data which can be kept in the controller state. However in many enterprise applications the data is usually model data and it can be used in other parts of the application or the form can be split into wizard steps that handle parts of a model. Therefore crizmas-form also allows us to connect models to our inputs.&lt;/p&gt;

&lt;p&gt;Of course we get typical APIs for resetting or clearing the inputs, submitting and getting the form data, adding and removing inputs dynamically from the form and also out of the box validators, but probably the most interesting capability of crizmas-form is &lt;a href="https://medium.com/@raul.mihaila/crizmas-status-update-and-the-form-interlaid-asynchronous-validations-4abf167a54bb"&gt;managing race conditions in interlaid async validations&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Scroll virtualization
&lt;/h4&gt;

&lt;p&gt;Enterprise applications typically have a lot of big tables of data. For this we provide our own implementation of scroll virtualization which allows us to display a big list of items without blocking the browser: only a part of the items are rendered while for the user it appears that all the items are rendered.&lt;/p&gt;

&lt;h4&gt;
  
  
  Based on React
&lt;/h4&gt;

&lt;p&gt;At the view level we use React. React is great because it provides huge flexibility which fits crizmas-mvc very well especially because we can use Javascript to create fragments of the view. Comparing this to the primary Vue templating language or the Angular templating language we immediately see a big difference in flexibility and ease of use, assuming you are comfortable with Javascript.&lt;/p&gt;

&lt;p&gt;A great benefit of using React is the community behind it, including the huge number of components that we can find online.&lt;/p&gt;

&lt;h4&gt;
  
  
  The MVC of crizmas-mvc
&lt;/h4&gt;

&lt;p&gt;There are different flavors of MVC and we don’t claim that ours is the best or the purest. It is important that we mention a few characteristics of our approach. Our approach to MVC is adapting it to a way of handling changes in the application in a more reactive way. Because of this, we will not see much of the observer pattern where the view and controller subscribe to the model in order to react to changes. Instead when we want something to happen in the application we need to go through the controller. The controller is where the framework does the work of updating the view after the operation finished. The view typically gets access to the controller and the controller may reveal model data/state as well, so the view can render it.&lt;/p&gt;

&lt;p&gt;The controller in general is not seen only as a glue between the view and the model. The controller is in fact smart, but it delegates to the model to manage the domain area. The controller can have some logic of transitioning to different contexts of the application for instance. And, of course, we need to respect the separation of concerns and so each controller will have its own scope and purpose.&lt;/p&gt;

&lt;p&gt;If in a more classical approach the controller could interact with the view in an imperative way, in our case when the controller needs to control the view, we can manage some state inside the controller and pass that to the view whose rendering behavior would then be determined by that state.&lt;/p&gt;

&lt;p&gt;The controllers can also interact with an API layer. The API layer would contain the details of communicating with a server. The operations of communicating with the server can be initiated from the controller. Also reacting when the communication finished, for instance by asking the model to update itself. These things can also happen in a service and if we were to introduce services, the controllers could interact with such services (without allowing the view to interact with the services). If we look at Angular services we can see that often they are a mix of the API layer, models and services as we’ve just described them above. Because there is a clear separation between the the API layer, controllers and models in crizmas-mvc, the services in our approach would be very slim, therefore we could actually have this part incorporated in controllers with a specific scope and responsibility.&lt;/p&gt;

&lt;p&gt;In general, in crizmas-mvc, we have route controllers whose interaction with the route view components is handled by the router (from crizmas-router). Beside these we have controllers with specific responsibilities. These are often composed inside a route controller. This gives great flexibility when it comes to structuring our code and implementing different pieces of functionality that can be reused in different contexts of the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why and when it’s good
&lt;/h3&gt;

&lt;p&gt;In order to see the benefits of crizmas-mvc we need complexity and a desire for productivity. In this way we can better weigh the disadvantages of lacking capabilities, sloppy APIs and rigid framework patterns. Probably the best use case for this framework is a big enterprise application with complex changing requirements. There have been attempts for comparing frameworks, but the use cases haven’t really been satisfying. We usually see ‘Todo MVC’ examples. There was also a more interesting attempt of comparing frameworks with an application that looks more like a &lt;a href="https://github.com/gothinkster/realworld"&gt;real world application&lt;/a&gt;, and you can see our crizmas-mvc implementation too (&lt;a href="https://github.com/raulsebastianmihaila/crizmas-mvc-realworld"&gt;repo&lt;/a&gt;, &lt;a href="https://raulsebastianmihaila.github.io/crizmas-mvc-realworld-site/"&gt;app&lt;/a&gt;), but even that is not relevant enough because it’s too simple. For crizmas-mvc an enterprise application would be more relevant.&lt;/p&gt;

&lt;p&gt;crizmas-mvc combines many great capabilities with a great deal of flexibility and separation of concerns to facilitate reusability and help you be productive even when the requirements are very complex.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compared to other frameworks/approaches
&lt;/h3&gt;

&lt;p&gt;We’ve already mentioned quite a few differences between crizmas-mvc and other frameworks. If we were to provide a very short summary we could mention:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the separation between controllers and views (and their lifecycle)&lt;/li&gt;
&lt;li&gt;the clear separation between the API layer, controllers and model (both compared to Redux and Vuex where controller logic can stay in many places as well as compared to Angular services which can mix the data layer with models and other service logic)&lt;/li&gt;
&lt;li&gt;possibility of instantiating models in controllers and not having to clear the model/store/service when the context of the application is changed&lt;/li&gt;
&lt;li&gt;the complete independence of the model with absolutely no constraints from the framework, which provides flexibility&lt;/li&gt;
&lt;li&gt;managing the pending states of trees of objects&lt;/li&gt;
&lt;li&gt;router capabilities (refresh from any fragment of the current chain of routes; API for adding, removing, listing and checking routes dynamically)&lt;/li&gt;
&lt;li&gt;form capabilities (event based validation; possibility of connecting models to inputs; managing race conditions in interlaid async validations)&lt;/li&gt;
&lt;li&gt;scroll virtualization&lt;/li&gt;
&lt;li&gt;we use React at the view layer so in this respect we benefit from the advantages that React brings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a few other notes that we can add to this topic.&lt;/p&gt;

&lt;p&gt;There seems to be quite some emphasis in a part of the front-end community on the importance of static typing and immutability in general. We don’t see things the same way as explained in &lt;a href="https://medium.com/@raul.mihaila/the-real-problem-with-programming-in-javascript-bfdb64d24211"&gt;an older article&lt;/a&gt;. Relevant experience solidifies our position. We’ve lead two teams on two complex enterprise applications, one with Redux and the other one with Vuex. No static typing was used and in terms of productivity we benefited from that. We also had a very small number of bugs. Immutability didn’t make a positive difference either (as with Vuex we do mutations). However, we do recognize a benefit of Flux, which is the restrictive organization of the codebase. This makes it easier for a team made of different people with different skills and experience to maintain consistency throughout the codebase. Less experienced developers can find more common patterns in the application and code review is easier to do as there are less ways of writing the code. When combined with immutability, Flux has the downside of being less intuitive as certain operations that depend on other operations that update the state of the application can be initiated from the component only after the store was updated and the new state was propagated through the view, typically in a &lt;em&gt;componentDidUpdate&lt;/em&gt; hook, assuming such state is only read through the props (with Redux the store state could be read directly through its API as well, but in that case we would be mixing approaches, while with Vuex we don’t have this issue because the state would not become stale). The restrictive nature of Flux also has the downside of being too rigid where more complexity would benefit from more flexible ways of doing things (for instance by reusing controllers that can hold local state). As for Typescript, we’ve also experienced with that in a different application together with Redux and we ran into quite a few library incompatibilities, out of date type definitions and obscure compilation error messages for things that would have worked with pure Javascript.&lt;/p&gt;

&lt;p&gt;Compared to Flux, with crizmas-mvc controller logic is easier to reuse in multiple contexts of the application since they can keep local state (especially if they don’t have to interact with a model that outlives the controller). With Redux, for instance, action creators, where such logic could be implemented, need a reducer in order to hold that state and you end up with a store module/reducer for each such controller context. You could also use higher order components or hooks for such controller logic, but their state would get lost on unmounting, so you would still rely on a store. If a separate state management mechanism is introduced for this purpose, it needs to propagate the new state to the components and the components need to subscribe to it, which means extra verbosity.&lt;/p&gt;

&lt;p&gt;With Redux and Vuex, for reusing store logic it’s possible to use mixins (assuming, in the case of Redux, that we define a mechanism with which we write the reducers as object methods and then transform the result into a normal Redux reducer), or, the simplest approach, we can use functions in a functional or procedural way (since with Vuex we do mutations). There is also the possibility of writing higher order reducers with Redux in order to reuse code. This is somewhat similar to using ids to identify the instance that we operate on. You could also do inheritance in a Flux store but that has its disadvantages.&lt;/p&gt;

&lt;p&gt;With crizmas-mvc, for reusing controller and domain model logic, we can also use mixins and functions. We can also take a more traditional OOP approach, which allows defining the state structure and logic for operating with that state locally in the same place (in the same object/class or closure). This way we can reuse logic with multiple instances without too much boilerplate and without resorting to binding ids to our operations. With crizmas-mvc controllers and models can also do traditional OOP composition (this implies being able to call methods of a child object, so we’re not referring only to composing fields). This allows us to structure the code more easily when we prefer an extra layer of fields for a certain purpose. It also allows traditional and easy to implement design patterns, such as the strategy pattern.&lt;/p&gt;

&lt;p&gt;Without inheritance and mixins, in Redux or Vuex the state is typically separate from the reused logic. The traditional OOP composition approach in this case would have the effect of mixing the state with methods which would mean that the store, which should contain a kind of state of the application in its entirety, would now also contain some functions. The store should be accessible from the components only for subscribing, reading and dispatching and nothing else. Any other interaction with the store, from the components, should happen through the Flux pipeline. We should be able to pass the entire state of the store to a component and if that state contained methods, then the component could interact with the store in a way that would not be in conformance with the Flux approach. In Vuex, the methods (the fields whose values are functions) would still be reactive, which would be a bit weird. In Flux stores, in general it’s possible to do such OOP composition though, if we have a mechanism of extracting the state without methods that would be passed to the components, which would mean more verbosity. It is also possible, for instance with Redux, to use some sort of OOP composition by discarding the instance that holds the methods after performing the operation. You can instantiate a constructor by passing the existing state, then call the method that would return the new state. In this way you can focus on the state and operations related to that state in the same place (which is good when different related methods operate on different parts of that state). This however comes with quite some boilerplate of creating objects from existing state every time, which anyway is typical for the pipeline approach based on immutability. But with crizmas-mvc we don’t need all this boilerplate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Based on experience with complex applications, crizmas-mvc provides missing capabilities for front-end engineers and is optimized for ergonomics. It’s a framework that promotes a flexible approach, which allows for long term productivity. We hope this article sparked your interest in alternative progressive approaches in the context of modern front-end development.&lt;/p&gt;

</description>
      <category>framework</category>
      <category>frontend</category>
      <category>crizmasmvc</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
