{"id":6999,"date":"2022-06-18T00:00:25","date_gmt":"2022-06-18T00:30:25","guid":{"rendered":"https:\/\/ultering.com\/it4us\/?p=6999"},"modified":"2022-10-15T18:39:25","modified_gmt":"2022-10-15T19:09:25","slug":"node-js-sequelize-todo-todoitem-project-4th-step","status":"publish","type":"post","link":"https:\/\/ultering.com\/it4us\/?p=6999","title":{"rendered":"NODE.JS: SEQUELIZE: MVC Project &#8211; 4TH STEP"},"content":{"rendered":"<p>Revision 2022.<\/p>\n<p>&nbsp;<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_73 counter-hierarchy ez-toc-counter ez-toc-white ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-69fc663827b5b\" class=\"ez-toc-cssicon-toggle-label\"><span class><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\" \/><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\" \/><\/svg><\/span><\/span><\/label><input type=\"checkbox\" id=\"ez-toc-cssicon-toggle-item-69fc663827b5b\" checked aria-label=\"Toggle\"><nav><ul class=\"ez-toc-list ez-toc-list-level-1 \"><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#TARGET\" title=\"TARGET\">TARGET<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#FAST_START\" title=\"FAST START\">FAST START<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#HOW_TO_USE_THIS_TUTORIAL\" title=\"HOW TO USE THIS TUTORIAL\">HOW TO USE THIS TUTORIAL<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#THE_TUTORIALS_APPROACH_FOR_A_HIGHER_LEVEL\" title=\"THE TUTORIAL&#8217;S APPROACH FOR A HIGHER LEVEL\">THE TUTORIAL&#8217;S APPROACH FOR A HIGHER LEVEL<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#THE_SIGHTSEEN_GUIDE\" title=\"THE SIGHTSEEN GUIDE\">THE SIGHTSEEN GUIDE<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#Extra_Setup_%E2%80%93_The_Scaffolding\" title=\"Extra Setup &#8211; The Scaffolding\">Extra Setup &#8211; The Scaffolding<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#Appjs_cleaning\" title=\"App.js cleaning\">App.js cleaning<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#Utils\" title=\"Utils\">Utils<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#Persistence_extra_configuration\" title=\"Persistence extra configuration\">Persistence extra configuration<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#DTOs\" title=\"DTOs\">DTOs<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#Favicon\" title=\"Favicon\">Favicon<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#TodoHelperjs\" title=\"TodoHelper.js\">TodoHelper.js<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#menuesj\" title=\"menu.esj\">menu.esj<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#Persistence_for_Todo_use_case\" title=\"Persistence for Todo use case\">Persistence for Todo use case<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#TodoDB\" title=\"TodoDB\">TodoDB<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#The_Todo_Object\" title=\"The Todo Object\">The Todo Object<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#THE_SERVICE_LAYER\" title=\"THE SERVICE LAYER\">THE SERVICE LAYER<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#CONCLUSION\" title=\"CONCLUSION\">CONCLUSION<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/ultering.com\/it4us\/?p=6999\/#SOURCE_CODE\" title=\"SOURCE CODE\">SOURCE CODE<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"TARGET\"><\/span>TARGET<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This tutorial is the 4th step of the <a href=\"https:\/\/ultering.com\/it4us\/?p=2729\">series<\/a> and its code evolves from the <a href=\"https:\/\/ultering.com\/it4us\/?p=2870\">3rd step<\/a>.<\/p>\n<p>The target is to apply Object-Oriented and MVC architecture concepts for a Todo site using relationship, where:<br>\nTodo 1 &#8212;&#8212;&#8211; + TodoItem<br>\nOne Todo may have one or more TodoItem instances.<\/p>\n<p>The concepts seen before will be applied in a more complex use case.<\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"FAST_START\"><\/span>FAST START<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><strong>&#8211; Help for linux (debian\/ubuntu) install:<\/strong><br>\n<a href=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/ultering_sequelize_tutorial_debian_install.txt\">ultering_sequelize_tutorial_debian_install<\/a><\/p>\n<p>After installing check the windows install below.<\/p>\n<p><strong>&#8211; Database user setup (just in the case):<br>\n<a href=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/postgres_user_setup.txt\">postgres_user_setup<\/a><\/strong><\/p>\n<p><strong><br>\n&#8211; Windows install:<br>\n<\/strong>1. Download source code from GitHub:<br>\n<strong><a href=\"https:\/\/github.com\/alsdias\/node_sequelize_ultering_ml40643_4th_step.git\">node_sequelize_ultering_ml40643_4th_step<\/a><\/strong><\/p>\n<p>2. Use the same node_modules dir created from <a href=\"https:\/\/ultering.com\/it4us\/?p=1953\">1st step<\/a>.<br>\nYou may move it to save time and disk space.<br>\nRemember, node_modules must be under project\u2019s root, in this case it is \u201cnode\u201d dir.<\/p>\n<p>3. Go to app root dir and edit the config.json user config dir.<br>\nSwitch the database configuration for your respective choice (dev\/local, cloud, etc.).<\/p>\n<p>4. Go to the app root dir and edit run.bat.<br>\nSet the APP_ENV envvar to match your choice.<br>\n<span style=\"color: #808000;\"><strong>Recommended to use your local database.<\/strong><\/span><br>\n<span style=\"color: #808000;\"><strong>ElephantSQL free plan will not work due to pool limit (see note below).<\/strong><\/span><\/p>\n<p>SET APP_ENV=dev<br>\nrem SET APP_ENV=cloud<\/p>\n<p><strong>Create your local PostgreSQL database instance and set its configuration in node\/config\/config.json file (topic #3).<\/strong><br>\nIt is not necessary to create the tables.<br>\nIt will be created by Sequelize and populated by the app.<br>\nJust log into your local database and do:<br>\ncreate database DBNAME<br>\n&#8211; For instance:<br>\ncreate database run455_dev<\/p>\n<p>5. Run the app:<br>\nrun.bat<\/p>\n<p>6. Point to:<br>\nhttp:\/\/localhost:3000\/<br>\nGo to menu and choose users.<br>\nClick on populate, then list.<\/p>\n<h2><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7088\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_4th_03.jpg\" alt width=\"600\" height=\"299\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_4th_03.jpg 600w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_4th_03-300x150.jpg 300w\" sizes=\"(max-width: 600px) 100vw, 600px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7088 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20600%20299%22%3E%3C%2Fsvg%3E\" alt width=\"600\" height=\"299\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20600%20299%22%3E%3C%2Fsvg%3E 600w\" sizes=\"(max-width: 600px) 100vw, 600px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_4th_03.jpg 600w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_4th_03-300x150.jpg 300w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_4th_03.jpg\"><\/h2>\n<p>To access Todo use case (story), go to menu and choose Tools.<br>\nClick on populate.<br>\nReturn to the menu and choose &#8220;List&#8221;.<\/p>\n<p>That&#8217;s it. Have fun! \ud83d\ude42<\/p>\n<p>GENERAL NOTES<\/p>\n<p>1. Although this tutorial uses PostgreSQL, it may be used any other database since the purpose of ORM is to provide a layer of abstraction for the database&#8217;s implementations. In this case, switch the configuration to match your choice, for instance, the &#8220;dialect&#8221; property value must be replaced by the new value from your choice.<\/p>\n<p>2.<strong> <em>IMPORTANT<\/em><\/strong>:<br>\n<span style=\"color: #333300;\"><strong>To protect clarity and keep the tutorial concise, the sequence and topics are provided in order to accomplish the main tutorial&#8217;s goal.<\/strong><\/span><br>\n<span style=\"color: #333300;\"><strong>Of course, some details may cause some discomfort to the reader depending on his own knowledge and understanding.<\/strong><\/span><\/p>\n<p><strong>3. The code available for download was implemented using Node.js v.16. Please, use the same version.<\/strong><\/p>\n<p><strong>4. The &#8220;elephantsql original: error: too many connections for role&#8221; issue.?<\/strong><\/p>\n<p class=\"text-2xl sm:text-3xl 2xl:text-2xl mt-8 mb-4 text-white\">ElephantSQL has a 5 connection limit on their free plan.<br>\nMore information at:<br>\n<a href=\"https:\/\/jaygould.co.uk\/2022-04-06-too-many-connections-for-role-error-postgres-serverless-vercel%20copy\/\">The &#8216;too many connections for role&#8217; error with Postgres on serverless<\/a><\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"HOW_TO_USE_THIS_TUTORIAL\"><\/span>HOW TO USE THIS TUTORIAL<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>1. Download the code from GitHub<\/p>\n<p class=\"wb-break-all\"><a href=\"https:\/\/github.com\/alsdias\/node_sequelize_ultering_ml40643_4th_step\">node_sequelize_ultering_ml40643_4th_step<\/a><\/p>\n<p>2. Watch the video to get an overview.<\/p>\n<p>3. Follow the &#8220;Sightseen&#8221;.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"width: 640px;\" class=\"wp-video\"><!--[if lt IE 9]><script>document.createElement('video');<\/script><![endif]-->\n<video class=\"wp-video-shortcode\" id=\"video-6999-1\" width=\"640\" height=\"360\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/20220620_182024.mp4?_=1\"><a href=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/20220620_182024.mp4\">https:\/\/ultering.com\/it4us\/wp-content\/uploads\/20220620_182024.mp4<\/a><\/video><\/div>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"THE_TUTORIALS_APPROACH_FOR_A_HIGHER_LEVEL\"><\/span>THE TUTORIAL&#8217;S APPROACH FOR A HIGHER LEVEL<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The previous steps were very important to get the grips with Node.js\/Express using Sequelize.<br>\nDue to its simplicity, it was possible to go step by step in a very detailed way.<br>\nWe&#8217;ve followed that strategy for the 1st, 2nd, and 3rd steps.<\/p>\n<p><strong><span style=\"color: #808000;\">The 4th step applies all the concepts seen before and jumps to the <a style=\"color: #808000;\" href=\"https:\/\/en.wikipedia.org\/wiki\/Model\u2013view\u2013controller\">MVC pattern<\/a> plus additional features.<\/span><\/strong><br>\n<strong><span style=\"color: #808000;\">If it was adopted the same strategy for this step, the tutorial would become too large, boring, and discouraging.<\/span><\/strong><br>\n<strong><span style=\"color: #808000;\">If you have been through the previous steps, the code will be self-explainable and the key points are described here through the &#8220;sightseen guide&#8221;. <noscript><img decoding=\"async\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/plugins\/wp-edit\/plugins\/emoticons\/img\/smiley-smile.gif\"><\/noscript><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/plugins\/wp-edit\/plugins\/emoticons\/img\/smiley-smile.gif\" class=\" lazyload\"><br>\nThis strategy becomes faster and straight.&nbsp;<\/span><\/strong><\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"THE_SIGHTSEEN_GUIDE\"><\/span>THE SIGHTSEEN GUIDE<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"Extra_Setup_%E2%80%93_The_Scaffolding\"><\/span>Extra Setup &#8211; The Scaffolding<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Most applications require extra stuff to support them.<br>\nIt is usually named &#8220;scaffolding&#8221;.<br>\nBelow, it details part of it as if it was created from the 3rd step.<br>\nIt is not necessary to follow it because the downloaded code is already complete.<br>\nUse it just to get acquainted with the new step and what was done to fulfill this step.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Appjs_cleaning\"><\/span>App.js cleaning<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Removed the commented code from app.js from the previous step.<br>\nNo more necessary. Before, it was used for testing purposes.<\/p>\n<p><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7030\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_15.jpg\" alt width=\"974\" height=\"423\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_15.jpg 974w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_15-300x130.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_15-768x334.jpg 768w\" sizes=\"(max-width: 974px) 100vw, 974px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7030 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20974%20423%22%3E%3C%2Fsvg%3E\" alt width=\"974\" height=\"423\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20974%20423%22%3E%3C%2Fsvg%3E 974w\" sizes=\"(max-width: 974px) 100vw, 974px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_15.jpg 974w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_15-300x130.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_15-768x334.jpg 768w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_15.jpg\"><\/p>\n<h3><\/h3>\n<h3><span class=\"ez-toc-section\" id=\"Utils\"><\/span>Utils<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This step leverages the application complexity to something near the real world.<br>\nThat way, we need extra support.<br>\nCreated the <em>utils<\/em> package on the app&#8217;s root dir for the utility classes that will help us with common tasks shared across the project \u2014 cohesion must be in mind all the time (avoid repeating code in different places).<\/p>\n<p><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7021\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_13.jpg\" alt width=\"190\" height=\"425\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_13.jpg 190w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_13-134x300.jpg 134w\" sizes=\"(max-width: 190px) 100vw, 190px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7021 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20190%20425%22%3E%3C%2Fsvg%3E\" alt width=\"190\" height=\"425\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20190%20425%22%3E%3C%2Fsvg%3E 190w\" sizes=\"(max-width: 190px) 100vw, 190px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_13.jpg 190w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_13-134x300.jpg 134w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_13.jpg\"><\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Persistence_extra_configuration\"><\/span>Persistence extra configuration<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>It was also created an extra file that will be used to choose if we desire to create or not the tables.<\/p>\n<p>echo. &gt; config\\createdb.json<\/p>\n<p>How does it work?<\/p>\n<p>When necessary to create the tables, set:<br>\n{&#8220;create_db&#8221;:&#8221;true&#8221;}<br>\nand run the app.<\/p>\n<p>After the first time, switch to false to preserve the data.<br>\n{&#8220;create_db&#8221;:&#8221;false&#8221;}<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"DTOs\"><\/span>DTOs<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>It uses <a href=\"https:\/\/en.wikipedia.org\/wiki\/Data_transfer_object\">DTO<\/a>s, a very resourceful pattern.<br>\nThe <a href=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/dto.7z\">dto.7z<\/a> files were added to <em>node\\models<\/em> .<\/p>\n<p><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7025\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_14.jpg\" alt width=\"154\" height=\"93\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7025 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20154%2093%22%3E%3C%2Fsvg%3E\" alt width=\"154\" height=\"93\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_14.jpg\"><\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Favicon\"><\/span>Favicon<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Favicon install procedure:<\/p>\n<ol>\n<li>Created the favicon image:<br>\n<a href=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/favicon.7z\">favicon.7z<\/a><br>\n.<\/li>\n<li>Moved the favicon to the node\\public\\images folder.<br>\n.<\/li>\n<li>Installed the favicon package:<br>\nnpm install serve-favicon<br>\n.<\/li>\n<li>Edited app.js and added the following snippet:<br>\nvar favicon = require(&#8216;serve-favicon&#8217;);<br>\napp.use(favicon(__dirname + &#8216;\/public\/images\/favicon.ico&#8217;));<br>\nor<br>\napp.use(favicon(path.join(__dirname,&#8217;public&#8217;,&#8217;images&#8217;,&#8217;favicon.ico&#8217;));<br>\n.<\/li>\n<li>Restarted the app (run.bat) and the browser.<br>\n.<\/li>\n<li>Tested, pointing to:<br>\nhttp:\/\/localhost:3000\/favicon.ico<br>\n.<\/li>\n<li>Pointed to the app:<br>\nhttp:\/\/localhost:3000\/users<\/li>\n<\/ol>\n<h3><\/h3>\n<h3><span class=\"ez-toc-section\" id=\"TodoHelperjs\"><\/span>TodoHelper.js<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>It provides extra operations to populate the todo&#8217;s database.<\/p>\n<p>The app.js is set to register it:<\/p>\n<div>\n<div>\n<p>var tdoRouter = require(&#8216;.\/routes\/todo&#8217;);<\/p>\n<div>\n<div>app.use(&#8216;\/todo&#8217;, todoRouter);<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div><\/div>\n<div>SUGGESTION<br>\nI usually like to organize the code by putting together similar statements.<br>\nFor instance:<\/div>\n<div>\n<div>\n<div><em>var indexRouter = require(&#8216;.\/routes\/index&#8217;);<\/em><\/div>\n<div><em>var usersRouter = require(&#8216;.\/routes\/users&#8217;);<\/em><\/div>\n<div><em>var todoRouter = require(&#8216;.\/routes\/todo&#8217;);<\/em><\/div>\n<\/div>\n<\/div>\n<div>\n<p><em>&#8230;<\/em><\/p>\n<div>\n<div><em>app.use(&#8216;\/&#8217;, indexRouter);<\/em><\/div>\n<div><em>app.use(&#8216;\/users&#8217;, usersRouter);<\/em><\/div>\n<div><em>app.use(&#8216;\/todo&#8217;, todoRouter);<\/em><\/div>\n<\/div>\n<\/div>\n<h3><span class=\"ez-toc-section\" id=\"menuesj\"><\/span>menu.esj<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This is the menu shared by all pages, and it is included using the following statement:<br>\n<em>&lt;%- include(&#8216;menu&#8217;) &nbsp;%&gt;<\/em><\/p>\n<div><\/div>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Persistence_for_Todo_use_case\"><\/span>Persistence for Todo use case<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>\n<h4><span class=\"ez-toc-section\" id=\"TodoDB\"><\/span>TodoDB<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<\/div>\n<div>This class is responsible for handling persistence operations for Todo objects.<br>\n<span data-preserver-spaces=\"true\">Instead of extending a class using inheritance, it may be referenced, a recommended design practice \u2014 &#8220;<\/span><a class=\"_e75a791d-denali-editor-page-rtfLink\" href=\"https:\/\/en.wikipedia.org\/wiki\/Composition_over_inheritance\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-preserver-spaces=\"true\">Favor Aggregation\/Composition over Inheritance<\/span><\/a><span data-preserver-spaces=\"true\">&#8220;, as mentioned previously.<\/span><\/div>\n<div><\/div>\n<div>Programming languages usually offer many alternatives to implementations.<br>\nAlthough being a good thing, it promotes an additional effort to start learning a new API.<br>\nHow do I do this?<br>\nWhich alternative should I choose?Sequelize is not an exception.<br>\nFor instance, you may extend a class from Model or not.<br>\nHere is an example extracted from the <a href=\"https:\/\/sequelize.org\/docs\/v6\/advanced-association-concepts\/creating-with-associations\/\">Sequelize documentation<\/a>.<\/div>\n<div><\/div>\n<div><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7051\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_doc_class_extends.jpg\" alt width=\"801\" height=\"584\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_doc_class_extends.jpg 801w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_doc_class_extends-300x219.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_doc_class_extends-768x560.jpg 768w\" sizes=\"(max-width: 801px) 100vw, 801px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7051 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20801%20584%22%3E%3C%2Fsvg%3E\" alt width=\"801\" height=\"584\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20801%20584%22%3E%3C%2Fsvg%3E 801w\" sizes=\"(max-width: 801px) 100vw, 801px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_doc_class_extends.jpg 801w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_doc_class_extends-300x219.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_doc_class_extends-768x560.jpg 768w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_doc_class_extends.jpg\"><\/div>\n<p>The example above uses the init method.<br>\nThis tutorial doesn&#8217;t use this approach.<br>\nAlternatively, the class does not extend from Model as you may check when comparing with the TodoDB.js code.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"The_Todo_Object\"><\/span>The Todo Object<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>This is how it looks like when retrieved by Sequelize query:<\/p>\n<p><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7064\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj.jpg\" alt width=\"1900\" height=\"1025\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj.jpg 1900w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj-300x162.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj-768x414.jpg 768w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj-1536x829.jpg 1536w\" sizes=\"(max-width: 1900px) 100vw, 1900px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7064 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201900%201025%22%3E%3C%2Fsvg%3E\" alt width=\"1900\" height=\"1025\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201900%201025%22%3E%3C%2Fsvg%3E 1900w\" sizes=\"(max-width: 1900px) 100vw, 1900px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj.jpg 1900w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj-300x162.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj-768x414.jpg 768w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj-1536x829.jpg 1536w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_obj.jpg\"><\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"THE_SERVICE_LAYER\"><\/span>THE SERVICE LAYER<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>In the previous code, the database had straight access.<br>\nThis is not the best approach.<br>\nSince we are following MVC pattern, the service is responsible to materialize the &#8220;use cases&#8221; (stories) and access the database.<\/p>\n<p>The DbSvc.js class contains the code that is common to all services, so the other services classes extend it.<\/p>\n<p>For example, the &#8220;populate&#8221; method uses a helper class and performs the database access.<br>\nEverything that concerns that feature that reflects a story remains in just one place, one layer.<\/p>\n<p><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7053\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todosvc_populate.jpg\" alt width=\"1019\" height=\"716\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todosvc_populate.jpg 1019w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todosvc_populate-300x211.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todosvc_populate-768x540.jpg 768w\" sizes=\"(max-width: 1019px) 100vw, 1019px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7053 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201019%20716%22%3E%3C%2Fsvg%3E\" alt width=\"1019\" height=\"716\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201019%20716%22%3E%3C%2Fsvg%3E 1019w\" sizes=\"(max-width: 1019px) 100vw, 1019px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todosvc_populate.jpg 1019w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todosvc_populate-300x211.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todosvc_populate-768x540.jpg 768w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todosvc_populate.jpg\"><\/p>\n<h3><\/h3>\n<p>Now, please compare the service with the TodoDB.js database class.<br>\nThere is just database stuff, no &#8220;stories'&#8221; (use cases) stuff, so there is no leak of concern.<br>\nThe database layer must deal with the database and nothing more.<br>\nService materializes features, but it doesn&#8217;t handle the database directly but through the database layer.<\/p>\n<h3><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7054\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_tododb.jpg\" alt width=\"797\" height=\"876\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_tododb.jpg 797w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_tododb-273x300.jpg 273w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_tododb-768x844.jpg 768w\" sizes=\"(max-width: 797px) 100vw, 797px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7054 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20797%20876%22%3E%3C%2Fsvg%3E\" alt width=\"797\" height=\"876\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20797%20876%22%3E%3C%2Fsvg%3E 797w\" sizes=\"(max-width: 797px) 100vw, 797px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_tododb.jpg 797w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_tododb-273x300.jpg 273w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_tododb-768x844.jpg 768w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_tododb.jpg\"><\/h3>\n<p>&nbsp;<\/p>\n<p>The control (routes\/navigation) is just a client that calls the service and everything else is transparent to it.<br>\nThis is the beauty of this pattern making it easy to implement and maintain an app.<\/p>\n<h3><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7056\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_route.jpg\" alt width=\"723\" height=\"460\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_route.jpg 723w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_route-300x191.jpg 300w\" sizes=\"(max-width: 723px) 100vw, 723px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7056 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20723%20460%22%3E%3C%2Fsvg%3E\" alt width=\"723\" height=\"460\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20723%20460%22%3E%3C%2Fsvg%3E 723w\" sizes=\"(max-width: 723px) 100vw, 723px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_route.jpg 723w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_route-300x191.jpg 300w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_todo_route.jpg\"><\/h3>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"CONCLUSION\"><\/span>CONCLUSION<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Everything shall be implemented in its own place, without having scattered code throughout the whole application that leads to confusion and madness when maintenance comes to play.<\/p>\n<p>Although JavaScript and C++ are flexible languages that make possible to mix styles, we shall avoid everything that could mess with the organization that supports a secure and fast way of implementing an application.<\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"SOURCE_CODE\"><\/span>SOURCE CODE<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><strong>Source code to download on GitHub <\/strong>using&nbsp; Node.js v.16<strong>, <a href=\"https:\/\/github.com\/alsdias\/node_sequelize_ultering_ml40643_4th_step.git\">node_sequelize_ultering_ml40643_4th_step<\/a><\/strong><\/p>\n<p><strong><a href=\"https:\/\/ultering.com\/it4us\/?p=2870\">Previous<\/a><\/strong><\/p>\n<p><strong>INDEX<\/strong>:<br>\n<a href=\"https:\/\/ultering.com\/it4us\/?p=2729\">NODE.JS: SEQUELIZE SERIES<\/a><\/p>\n<p>&nbsp;<\/p>\n<p><strong>BIBLIOGRAPHY<\/strong><\/p>\n<p><a href=\"https:\/\/sequelize.readthedocs.io\/en\/rtd\/articles\/getting-started\/\">sequelize.readthedocs.io\/en\/rtd\/articles\/getting-started\/<\/a><br>\n<a href=\"https:\/\/sequelize.org\/master\/manual\/model-instances.html\">sequelize.org\/master\/manual\/model-instances.html<\/a><br>\n<a href=\"https:\/\/sequelize.org\/master\/manual\/migrations.html\">sequelize.org\/master\/manual\/migrations.html<\/a><br>\n<a href=\"https:\/\/sequelize.org\/master\/manual\/raw-queries.html\">sequelize.org\/master\/manual\/raw-queries.html<\/a><\/p>\n<h2><\/h2>\n<div style=\"margin-top: 50px;\">&nbsp;<\/div>\n[ML40253]\n<!--CusAds0-->\n<div style=\"font-size: 0px; height: 0px; line-height: 0px; margin: 0; padding: 0; clear: both;\"><\/div>","protected":false},"excerpt":{"rendered":"<p>Revision 2022. &nbsp; TARGET This tutorial is the 4th step of the series and its code evolves from the 3rd step. The target is to apply Object-Oriented and MVC architecture concepts for a Todo site using relationship, where: Todo 1 &#8212;&#8212;&#8211; + TodoItem One Todo may have one or more TodoItem instances. The concepts seen &#8230; <a href=\"https:\/\/ultering.com\/it4us\/?p=6999\" class=\"more-link\">Read More<span class=\"screen-reader-text\"> &#8220;NODE.JS: SEQUELIZE: MVC Project &#8211; 4TH STEP&#8221;<\/span> &raquo;<\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[152,17,26,143],"tags":[],"class_list":["post-6999","post","type-post","status-publish","format-standard","hentry","category-dp","category-database","category-javascript","category-web-design"],"_links":{"self":[{"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/posts\/6999","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6999"}],"version-history":[{"count":6,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/posts\/6999\/revisions"}],"predecessor-version":[{"id":7135,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/posts\/6999\/revisions\/7135"}],"wp:attachment":[{"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6999"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6999"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6999"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}