<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Mateusz (mat3e) on Medium]]></title>
        <description><![CDATA[Stories by Mateusz (mat3e) on Medium]]></description>
        <link>https://medium.com/@mat3e?source=rss-f9485a48cfa2------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*FH3tWhoSEdPr0kyJkIj0Yw.jpeg</url>
            <title>Stories by Mateusz (mat3e) on Medium</title>
            <link>https://medium.com/@mat3e?source=rss-f9485a48cfa2------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 17 May 2026 01:54:05 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@mat3e/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Java’s default access]]></title>
            <link>https://medium.com/glovo-engineering/javas-default-access-7153b476ff5d?source=rss-f9485a48cfa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/7153b476ff5d</guid>
            <category><![CDATA[packaging]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[domain-driven-design]]></category>
            <category><![CDATA[modularity]]></category>
            <dc:creator><![CDATA[Mateusz (mat3e)]]></dc:creator>
            <pubDate>Wed, 01 Jun 2022 07:36:14 GMT</pubDate>
            <atom:updated>2022-06-01T07:41:39.341Z</atom:updated>
            <content:encoded><![CDATA[<p>Within my team, we like to challenge each other, question things and enforce a pragmatic, hands-on approach. Therefore, it was no surprise the following conversation started on Slack:</p><blockquote>Just a bit side-off discussion — what kind of benefits does the package-private give? I mean more specific than “better encapsulation”. More like “what kind of problems you faced before that this strategy would mitigate/solve”?</blockquote><p>I probably wrote too much, as teammates suggested converting it into a blog post…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x2uqpLGRAbe-NJTGA3UgXQ.png" /><figcaption>The approach which provoked the discussion</figcaption></figure><h3>Modularity</h3><p>Why do we use private fields and methods when everything can be just public? List all the pros and most (if not all) of them would work at the package level. Then, at the module level, at the microservice level, etc.</p><p>High cohesion &amp; encapsulation to put it simply. But it’s not all.</p><p>It’s all about making better abstractions and a more dev-friendly codebase. Reading code is more frequent than actual coding and it’s useful to have something like a table of contents to quickly verify if you look at the part that is worth reading at the moment. I see a proper usage of packages and package-private access as that.</p><p>Also, in that limited situations when you actually write code (😉), having much lower number of available classes/methods to choose from, makes it easier to choose a proper one. Less erroneous, and less likely to misuse that part of the codebase.</p><h3>Enforcing package-by-feature approach</h3><p>Still one can say, the world didn’t collapse because of not using package-private access. I think the same can be said about many other things, but is that our only metric?</p><p>How about organizing code using <em>package-by-feature</em> approach? It’s not as extreme as with package-private access, but I think most code I’ve seen was organized rather with <em>package-by-type</em> (a.k.a. <em>package-by-layer</em>) approach. Especially when counting in front-end codebases I worked with. Most code is organized like that, but it doesn’t mean it’s easier to work with such a code. See nice, thought-provoking examples at the end of this article: <a href="http://www.javapractices.com/topic/TopicAction.do?Id=205">http://www.javapractices.com/topic/TopicAction.do?Id=205</a>.</p><p>I think it’s obvious, but let me emphasize it</p><ul><li><em>Package-by-feature</em> helps to have package-private access</li><li>Using package-private access makes you think more in <em>package-by-feature</em> manner</li><li>Contrary, <em>package-by-layer</em> forces you to use public access to make classes from different packages visible to each other</li></ul><h3>Default</h3><p>There is another reason people don’t use package-private access as much as they could. It was meant to be default access (Java design), but then IDEs and alternative JVM languages made public a default. My (educated) guess is they went that way because <em>package-by-layer</em> approach was encouraged by Java EE, Grails and other frameworks.</p><p>Taking a wonderful IntelliJ as an example, you have 3 places to override settings to encourage package-private access:</p><ol><li>Check <em>Show Visibility Icons</em> in <em>Project Window</em> -&gt; <em>Tree Appearance</em></li><li>Modify <em>File and Code Templates</em> under <em>Preferences</em></li><li>Check a proper option under <em>Code Style</em> -&gt; <em>Java</em> -&gt; <em>Code Generation</em></li></ol><p>Because public is effectively a default, it’s in many articles, code examples, open source projects, etc. So fewer people think package-private access is useful, etc. And it drives itself.</p><p>Nevertheless, the original idea was to have a different default 🙂</p><h3>Join the elite 😉</h3><p>Despite the above, frameworks like Spring and JUnit 5 (fun fact: version 5 premiered in 2017) worked with Java’s default from the very beginning. So it’s not like no one was thinking about the package-private access. I’d even call these two <em>Top Performers</em> and I prefer taking the inspiration from them 😉</p><h3>Implementing well-known patterns</h3><p>There is a huge library of software design/integration/architecture patterns. You might not like package-private access, but willing to use e.g. <a href="https://martinfowler.com/eaaCatalog/serviceLayer.html">Service Layer</a>. My recommendation is to treat package-private access as a more convenient way of introducing the pattern. Treat it as an implementation detail and a helping technique.</p><h3>Smarter code organization</h3><p>One can still say packages should be used to organize the code and push towards <em>package-by-feature</em> approach and having 20+ package-private classes and one public <em>Service</em> or <em>Facade</em> class might not be the ideal organization.</p><p>My response is with Java’s default access as a default option you still use (sub)packages as the organizing structure, but you use them smarter 😄</p><ul><li>REST API and DTOs can go to a separate subpackage. It’s even better because you ensure RestController doesn’t expose anything “internal” from the part of the system</li><li>Considering CQRS, a whole <em>Query</em> part can be a dedicated subpackage, containing just public classes</li><li>The whole infrastructure part created with Spring can be a dedicated subpackage (Spring works perfectly with package-private access, remember? 🙂)</li><li>Design patterns requiring class hierarchies can have their dedicated subpackages. E.g. strategy subpackage with a public interface and all package-private implementations</li></ul><p>Thanks to promoting package-private access, you also discover files as a way of organizing your code. Something between the class and the package. I’d say it’s even encouraged with Java 16+ sealed classes, which can skip permits for same-file implementations.</p><p>Apart from files, I observed I started using Maven/Gradle modules better. E.g. you can extract adapters or api modules and use the same packages between them. So effectively you have like 20+ classes under a package but split into 2+ modules.</p><h3>Real-life benefits</h3><p>There are people much smarter than I who promote package-private access. I recommend taking a look at J. Bloch, <em>Effective Java</em>. Precisely, <em>Item 15: Minimize the accessibility of classes and members. </em>I also recommend watching</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FKrLFs6f2bOA%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKrLFs6f2bOA&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FKrLFs6f2bOA%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/d0e96202f066bc79c5a4358dcddd2db3/href">https://medium.com/media/d0e96202f066bc79c5a4358dcddd2db3/href</a></iframe><p>And my personal experiences connected with the above:</p><p>1. Not only I watched that talk 20+ times, but I also worked with the presented code for a moment, so I have some insight knowledge 😄</p><ul><li>It was something called “team tourism” at the company I worked and the presenter was on vacation when I worked with his team</li><li>System was developed for a couple of years already and I was able to introduce a new, quite serious feature within a week. I mean from 0 to deploy it on production. I started working on Monday and the next Monday I got my first feedback from the end users (it was a back-office app)</li></ul><h3>Mateusz Chrzonstowski (mat3e) on Twitter: &quot;I joined one of #developers team last Monday, I finished my task on Thursday, it was deployed on Friday. Today, I got first feedback from the end users.The power of #Microservices 😎 / Twitter&quot;</h3><p>I joined one of #developers team last Monday, I finished my task on Thursday, it was deployed on Friday. Today, I got first feedback from the end users.The power of #Microservices 😎</p><ul><li>There was a new team member there as well and he introduced a change, making one thing public. It was immediately caught by reviewers and comments were not like “rename this method”, but rather “is this a responsibility of that module”, “should this module know about that/expose that”, etc. Modularity was just a part of the team’s DNA. I see this as a side-effect of design, because looking at the team seniority, etc., it wasn’t a very experienced team</li></ul><p>2. Closer to what is highlighted by Joshua Bloch — I guess you faced API versioning problems, didn’t you? When you have REST/events and there are already clients/other systems using them, you need to support old versions for almost forever 😄</p><ul><li>In one team we decided to introduce service clients rather than public API. Then, package-private access was really handy to hide things. Similarly to what you do with limiting your REST services, but at the code level. I also used service clients later, in another company, and just interfaces were left public there</li><li>I also have some experience with autoconfigs, libraries and software plugins. Package-private access really makes these things easier to maintain. Contrary, what’s public has to be treated as “published” there</li></ul><h3>TL;DR</h3><p>Modularity, ownership, security/confidence and freedom to change 😄</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZrxSPMvnroiv6InEAKZS1g.png" /><figcaption>Part of the actual comment touching on the topic</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7153b476ff5d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/glovo-engineering/javas-default-access-7153b476ff5d">Java’s default access</a> was originally published in <a href="https://medium.com/glovo-engineering">The Glovo Tech Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How many AWS services do you need to host a static webpage? (2/2)]]></title>
            <link>https://medium.com/warsawjs/how-many-aws-services-do-you-need-to-host-a-static-webpage-2-2-aa619fc99fc2?source=rss-f9485a48cfa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/aa619fc99fc2</guid>
            <category><![CDATA[aws-lambda]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[web-hosting]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[website]]></category>
            <dc:creator><![CDATA[Mateusz (mat3e)]]></dc:creator>
            <pubDate>Thu, 13 Feb 2020 11:42:58 GMT</pubDate>
            <atom:updated>2022-10-23T17:12:31.930Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://medium.com/warsawjs/how-many-aws-services-do-you-need-to-host-a-static-webpage-1-2-b811929a9436">4 AWS services are good for a static website hosting</a>, but don’t forget we had a visitor counter to deal with. How many services are needed for this?</p><h3>Storage</h3><p>Counter’s state has to be stored somewhere. Amazon offers a NoSQL database, but I was afraid it was too much. I googled a bit (with <a href="https://duck.com/">duckduckgo.com</a> 😛) and found something which calmed me:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vo0_1-tfr8Z5Ug8pK7AErA.png" /><figcaption><a href="https://stackoverflow.com/questions/50212300/how-would-i-create-a-global-counter-for-aws-lambda-functions">source</a></figcaption></figure><p>After reading that, I’ve created a simple table in DynamoDB (5). It’s a key-value store, so you can have an entry like that:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2eBo9Ef750LYHLCSvh1TzQ.png" /><figcaption>DynamoDB table — id (a key) and the counter value</figcaption></figure><h3>Lambda (6)</h3><p>The logic behind the counter: to get its value, increment it, store a new value, return it through HTTP.</p><p>It’s not much, but it’s too much for a simple database. I went for AWS Lambda, which allows executing a simple code snippet. <em>Serverless</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1_9Q2iFDrJTAbmoM0n0p1Q.png" /><figcaption><a href="https://expeditedsecurity.com/aws-in-plain-english/">Amazon Web Services In Plain English</a></figcaption></figure><p>The best way of creating Lambda with an access to DynamoDB, exposed to the outer world is to create it from a blueprint. There is an existing template “microservice-http-endpoint” which does everything we want. With NodeJS:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qrBKKVQOuTtTNwJup24PJQ.png" /><figcaption>Creating Lambda from blueprint</figcaption></figure><p>Behind the scenes, this blueprint configures also CloudWatch (7), API Gateway (8) and the corresponding IAM roles and policies (9).</p><p>Wow.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WuxdLE11av5VVyE_3HU6ow.png" /><figcaption>Created Lambda</figcaption></figure><h4>IAM</h4><p>Let’s start from the end. IAM stands for Identity and Access Management. This is a formalized way of handling permissions. S3 Bucket Policy was just for S3 and here we have a central place for all the policies.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/468/1*861B4ir8U6hZb5v6eqoeMw.png" /><figcaption>Overview of AWS IAM</figcaption></figure><p>Blueprint adds us a single role containing 2 policies: for Lambda to read from and write to DynamoDB and for Lambda to write to CloudWatch.</p><p>Roles and polices defined in IAM can be reused all over the services.</p><h4>CloudWatch</h4><p>This is a place when you can monitor your services — check logs and metrics and see some nice charts, telling you e.g. what is the average execution time of your Lambda and so on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ia0vt-oNfzt68UT41XIZaQ.png" /><figcaption><a href="https://expeditedsecurity.com/aws-in-plain-english/">Amazon Web Services In Plain English</a></figcaption></figure><h4>API Gateway</h4><p>This is your way to expose something like Lambda from AWS! The screenshot tells it all:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hMUOMnGIe60XczRW1m2I3w.png" /><figcaption>API Gateway overview</figcaption></figure><p>Each building block is a place where you can add something, like e.g. additional mapping to the flow.</p><p>In API Gateway you can also configure which HTTP methods you want to support, you can go for Actions and enable CORS (it was needed to make a call from the browser) and you can specify stages on which everything is available. Example stages would be <em>dev</em>, <em>test</em> and <em>prod</em>. Then, you can expose different Lambdas under different stages or have the same Lambda, but e.g. with different Gateway limits, depending on the stage.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Y14UsIB0yF2D2XR7mZYZxA.png" /><figcaption>Stage Editor in API Gateway</figcaption></figure><h3>Show me the code!</h3><p>As mentioned, you can write your Lambda logic using NodeJS. I used the 8th version of the runtime, but you can also choose Node 10 recently.</p><p>What is nice in both versions you can use async/await and then, what is returned, will be a response body and what is thrown and not caught, will cause an error response.</p><pre>const AWS = require(&#39;aws-sdk&#39;);<br>const doc = require(&#39;dynamodb-doc&#39;);<br><strong>AWS.config.update({ region: &#39;eu-west-1&#39; });</strong><br>const dynamo = new doc.DynamoDB();</pre><pre>const TableName = &#39;table&#39;;<br>const Key = { id: 1 };</pre><pre><strong>exports</strong>.bumpCounter = async(event, context) =&gt; {<br>  const {Item: {counter}} = <strong>await dynamo.getItem({TableName, Key}).promise()</strong>;<br>  return {<br>    statusCode: 200,<br>    body: JSON.stringify(<br>      (await dynamo.updateItem({<br>        TableName,<br>        Key,<br>        <strong>UpdateExpression: &#39;set #C = :counter&#39;</strong>,<strong><br>        </strong>ExpressionAttributeNames: <strong>{ &#39;#C&#39;: &#39;counter&#39; },<br>        </strong>ExpressionAttributeValues: <strong>{ &#39;:counter&#39;: (counter + 1) },</strong><br>        <strong>ReturnValues: &#39;UPDATED_NEW&#39;</strong><br>      }).promise()).<strong>Attributes</strong><br>    )<br>  };<br>};</pre><p>At the beginning of the snippet, there are imports to use AWS mechanisms. To be 100% sure everything happens in my region of choice, I set it at the beginning with AWS.config.update function.</p><p>What is exported is our lambda. It’s an async function, which consumes 2 parameters — an event which triggered Lambda (HTTP request and its details) and the Lambda context. In the context you can have e.g. variables, which can be defined when configuring Lambda.</p><p>Then, I use DynamoDB client, which can work with await thanks to its promise() method. And, personally, I found these Expression things from updateItem confusing. At the beginning I had an update expression like</p><pre>`set counter = ${counter + 1}`</pre><p>but it was problematic as counter is a reserved DynamoDB keyword and there were some problems with the value passed like that. Therefore, I used template mechanisms from the client, where #alias is an alias for a table column and :alias — for its value.</p><p>It’s worth setting ReturnValue to &#39;UPDATED_NEW&#39; to get a response with the changed database columns. Accessing Attributes from this response will give us exactly that.</p><p>In case of errors, you should rely on CloudWatch. I found it really helpful together with a plain ol’ console.log.</p><p>To be super safe when it comes to costs, you can set a number of possible parallel lambdas to 1.</p><h3>What next?</h3><p>Adding a simple visitor counter to our webpage, brought up another 5 services: DynamoDB, Lambda, CloudWatch, API Gateway and IAM.</p><p>But it’s not over.</p><p>Everything can be improved, e.g. by limiting CloudFront just to European countries and by limiting the access to S3 — it could be available only for CloudFront.</p><p>Also, what if our webpage becomes super popular and we will get close to DynamoDB/Lambda limits?</p><p>I encourage you to start <strong>#AwsVisitorCounterChallenge</strong> and to create a visitor counter with as many AWS services, as it makes sense. On your own!</p><h3>Bonus: Chrzonstowski’s law</h3><p>With my simple webpage I learned a lot about cloud computing. And reading about all the services and AWS users made me think about when should or shouldn’t you use a public cloud infrastructure.</p><p>As there is an empirical Conway’s law, I decided to make my own. If there is already something like this, just let me know. If no — enjoy a new law 😁</p><blockquote>The larger the company the less, the more, the less and the more public cloud computing it needs.</blockquote><p>[hypothesis] Until becoming a new public cloud provider.</p><figure><img alt="Chrzonstowski’s law" src="https://cdn-images-1.medium.com/max/1024/1*OnSIMWo3O0wIdBpM49dDNA.png" /><figcaption>Chrzonstowski’s law</figcaption></figure><p>It makes sense, doesn’t it? The higher on the y-axis, the more public cloud is used. Being on the “growing” part of the graph means the company is moving some of its work to the public cloud and — contrary — “falling down” part of the red line means the company is moving OUT of the public cloud.</p><p>Our lovely website as well as startups are almost 100% in the clouds.</p><p>Then, my company, allegro (which has like 17 mln users and 1 mln daily transactions) is using <a href="https://youtu.be/OUFKBZFnjns">its own data centers</a> to host 800+ microservices.</p><p>Then, Pokemon GO, which you could think was dead, appeared to get <a href="https://www.forbes.com/sites/insertcoin/2018/06/27/pokemon-go-is-more-popular-than-its-been-at-any-point-since-launch-in-2016/#5eaab766cfd2">147 mln active users in May, 2018</a>. Number of users vary, depending on many conditions (e.g. the weather), so the scalability possibilities granted by the cloud are really important in this case. Pokemon GO relies on <a href="https://www.theserverside.com/feature/How-Pokemon-Go-created-a-Kuburnetes-powered-Java-cloud">NoSQL database from Google Cloud and is the biggest deployed Kubernetes cluster. Ever</a>.</p><p>Then, there is Dropbox with its outstanding number of 500 mln users. By moving out from AWS S3 to its own tech, <a href="https://www.geekwire.com/2018/dropbox-saved-almost-75-million-two-years-building-tech-infrastructure/">Dropbox saved $75 mln in 2 years</a>.</p><p>And, finally, we have Netflix. It is well-known AWS customer with 152 mln users, but <a href="https://expandedramblings.com/index.php/netflix_statistics-facts/">almost twice as many people who actually use it</a>. Netflix has heavy calculations per user and it uses its own CDN (<a href="https://www.networkworld.com/article/3037428/netflix-is-not-really-all-in-on-amazon-s-cloud.html"><em>The best way to express it is that everything you see on Netflix up until the play button is on AWS, the actual video is delivered through our CDN</em></a>).</p><p>Will Netflix become the next public cloud provider? We will see… At some point in time, Amazon went this way to make use of its servers, which were not used up until Black Fridays and other Boxing Days.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aa619fc99fc2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/warsawjs/how-many-aws-services-do-you-need-to-host-a-static-webpage-2-2-aa619fc99fc2">How many AWS services do you need to host a static webpage? (2/2)</a> was originally published in <a href="https://medium.com/warsawjs">WarsawJS</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How many AWS services do you need to host a static webpage? (1/2)]]></title>
            <link>https://medium.com/warsawjs/how-many-aws-services-do-you-need-to-host-a-static-webpage-1-2-b811929a9436?source=rss-f9485a48cfa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/b811929a9436</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[vuejs]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[web-hosting]]></category>
            <dc:creator><![CDATA[Mateusz (mat3e)]]></dc:creator>
            <pubDate>Tue, 04 Feb 2020 16:28:24 GMT</pubDate>
            <atom:updated>2020-02-29T23:08:13.691Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tYdOtllboR4bnKqQs3KGcA.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/F2HTC_CF4Jo?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Dallas Reedy</a> on <a href="https://unsplash.com/search/photos/cloud?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>The public cloud is just happening. Period.</p><p>I knew some of AWS/Azure/GCP services by their names and functions, but I really wanted to gain hands-on experience in using them.</p><p>As with (probably) most programmers, I created a couple of webpages one of which was for a member of my family. I’m ashamed of what it looks like now, but I still maintain it. Recently, I had to change its hosting, so… I decided to use AWS! To do what was needed and to achieve what I wanted.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/501/1*3mhKXi-2qxKV3-MacBVsMQ.jpeg" /></figure><h3>JS modifications</h3><p>First things first, let’s start with a JS code. The webpage was almost 100% static, with a visitor counter. PHP script was using a text file to store the number of visitors and to increment it. What’s worse, there were HTML frames to get around the problem of calculating visits after refreshing the page.</p><p>I’ve almost never used Vue, so it was a natural choice. I created 2 components in the index.html:</p><ol><li>For the main context of the webpage</li><li>For the “intro”, disappearing after the first click:</li></ol><pre>const Intro = {<br>  data: function () {<br>    return {<br>      <strong>shouldHide</strong>: !!sessionStorage.getItem(&#39;shouldHide&#39;)<br>    }<br>  },<br>  template: &#39;&lt;div <strong>v-if=&quot;!shouldHide&quot;</strong> <strong>@click=&quot;startPage&quot;</strong> style=&quot;<em>(...)</em>&quot;&gt;&lt;img src=&quot;img/bg.jpg&quot; style=&quot;<em>(...)</em>&quot;&gt;&lt;/div&gt;&#39;,<br>  methods: {<br>    <strong>startPage</strong>: function () {<br>      const vm = this;<br>      vm.shouldHide = true;<br>      <strong>sessionStorage.setItem(&#39;shouldHide&#39;, true);</strong><br>      const reqresp = new <strong>XMLHttpRequest</strong>();<br>      reqresp.onreadystatechange = function () {<br>        if (reqresp.readyState == 4 &amp;&amp; reqresp.status == 200) {<br>          <strong>const counter = JSON.parse(reqresp.responseText).counter;<br>          vm.$emit(&#39;got-counter&#39;, counter);<br>          sessionStorage.setItem(&#39;counter&#39;, counter);</strong><br>        }<br>      };<br>      reqresp.open(&#39;GET&#39;, <em>url</em>, true);<br>      reqresp.send();<br>    }<br>  }<br>}</pre><p>Old browsers had to be supported (😢) and configuring Babel with build scripts was too much. While <a href="https://caniuse.com/#feat=const">const works with IE11</a>, <a href="https://caniuse.com/#feat=fetch">fetch</a> and <a href="https://caniuse.com/#feat=arrow-functions">arrow functions</a> don’t.</p><p>Why having HTTP requests here? As you can see from the emitted event name, it is something connected with the new counter mechanism. We’ll come back to it later.</p><p>Also, to get around the multiple visits on refresh problem, <a href="https://caniuse.com/#feat=namevalue-storage">we have </a><a href="https://caniuse.com/#feat=namevalue-storage">sessionStorage</a>. Why not localStorage? The answer is <a href="https://softwareengineering.stackexchange.com/a/290571/336516">EU Cookie Law</a>. It seems sessionStorage doesn’t require you to have this terrible <em>Cookie Policy info</em> on your webpage.</p><h3>Files in clouds</h3><p>How to host static files? AWS S3 (1) is the answer! S3 means SSS which means Simple Storage Service. Moreover, it can be configured to expose a <em>bucket</em> content as a website! I thought my job was done there.</p><p>It wasn’t.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/670/1*sCOkOG1AoNzmQ4N_RWVdiQ.png" /><figcaption><a href="https://www.reddit.com/r/ProgrammerHumor/comments/9ym7mj/aws_in_a_nutshell/">source</a></figcaption></figure><p>OK, what is the “bucket”? It is something like a folder on your computer. Creating it is really simple, but there are some tricky parts.</p><ul><li>Choose its name carefully. For the webpage like <em>example.com</em>, bucket should be named <em>example.com</em> as well. Moreover, the name has to be unique across all the existing AWS buckets</li><li>Always choose an appropriate AWS Region. A rule of thumb for simple scenarios: the same Region for all the services to minimize the costs (Internet transfer between different parts of the world). I decided to go with <em>EU (Ireland)</em></li><li>Default options are OK in almost all the cases. However, your website should be available from the outside, so you should <strong>disable</strong> <em>blocking public and cross-account access</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b1_N7A-vwwzR_W72qNWwfA.png" /><figcaption>AWS S3 Permissions</figcaption></figure><p>Then, you can create <em>Bucket Policy</em> to specify the mentioned open access:</p><pre>{<br>    &quot;Version&quot;: &quot;2012-10-17&quot;,<br>    &quot;Statement&quot;: [<br>        {<br>            &quot;Sid&quot;: &quot;PublicReadGetObject&quot;,<br>            &quot;Effect&quot;: &quot;Allow&quot;,<br>            &quot;Principal&quot;: &quot;*&quot;,<br>            &quot;Action&quot;: &quot;s3:<strong>GetObject</strong>&quot;,<br>            &quot;Resource&quot;: &quot;arn:aws:s3:::<strong>example.com</strong>/*&quot;<br>        }<br>    ]<br>}</pre><p>Having these things fixed, you can upload all the files to your bucket and go for <em>Properties → Static website hosting</em>. You need to choose a main file (index.html) and — optionally — an error file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nA6Zwxu6nuecOZowCPx4hA.png" /><figcaption>AWS S3 Properties</figcaption></figure><h3>Domain?</h3><p>If URL like <a href="http://example.com.s3-website-eu-west-1.amazonaws.com">http://<strong>example.com</strong>.s3-website-eu-west-1.amazonaws.com</a> works for you, you can stop right now. But it wasn’t enough for me.</p><p>I had a nice domain, managed through OVH and I wanted to connect it with my S3 files.</p><h4>Managing in OVH</h4><p>First try was to <a href="https://stackoverflow.com/a/51008021/4774651">add S3 URL as CNAME DNS record in OVH management tool</a>. <a href="https://en.wikipedia.org/wiki/CNAME_record">CNAME means Canonical Name and it can just lead to a different domain</a>. Sounds good, doesn’t work — OVH requires providing an absolute URL. With “.” at the end. And using S3 address with a dot at the end leads to 404 error (<em>NoSuchBucket</em>).</p><p>At least, it happened to me.</p><h4>AWS distribution</h4><p>Googling a little never killed anybody. It appeared, there is a dedicated AWS service for distributing files, AWS <a href="https://en.wikipedia.org/wiki/Content_delivery_network">CDN </a>— CloudFront (2). Distributing files may not sound as the solution for the domain problem, but CloudFront offers some configuration options connected with this topic.</p><p>When creating a distribution, remember about a <em>default root object</em>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aezYssMwjAVrX5_yqhgvPg.png" /><figcaption>CloudFront config</figcaption></figure><p>It took some time to distribute all the files, but then, loading the webpage with CDN URL was much faster.</p><p>Using this CDN URL as CNAME? Nope.</p><pre>403 ERROR<br>The request could not be satisfied.<br>Bad request.</pre><pre>Generated by cloudfront (CloudFront)</pre><pre>Request ID: xxx</pre><p>CloudFront allows providing alternative domains, but you need a certification — a proof it is really your domain. I gave up and switched from OVH to AWS. It’s easier to configure the certification this way.</p><h4>Managing in AWS</h4><p>I started managing my domains from AWS Route 53 (3).</p><blockquote><strong>Warning</strong>: Route 53 is something you have to pay for. Each Hosted Zone costs like 0.62 $, including tax. Costs of S3, CloudFront and others are skippable for tiny scales. Moreover, as a new user, you have a free tier, but Route 53 has its fixed price.</blockquote><p>The goal is to create a Hosted Zone in Route 53 for the domain and then, it is super easy to plug S3 or CloudFront URL there. Well… should be, but there are 2 things to be fixed first.</p><ol><li>DNS servers in OVH Control Panel</li><li>HTTPS</li></ol><p>Switching from OVH to Route 53 is as simple as playing with “DNS servers” tab in OVH Control Panel. Provide Route 53 servers there:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QoXTkS9qxRPMxwd-iJ1MEw.png" /><figcaption>OVH DNS servers option</figcaption></figure><h3>HTTPS</h3><p>Why do we need it? Not even because it’s a standard nowadays, but because CloudFront requires it for its alternative domains.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JgHplXKsX0BAFMnrdOVEyQ.png" /><figcaption>CloudFront Distribution Settings</figcaption></figure><p>As stated in the above screenshot, you can use ACM (AWS Certificate Manager) (4) to get the SSL Certificate. It’s as simple as clicking</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-QNPTwbcn9J6BpREX1g8Rw.png" /><figcaption>AWS Certificate Manager option</figcaption></figure><p>and going with default options.</p><p>I’ve just defined an <em>Alternate Domain Name</em> in CloudFront Distribution Settings and filled the SSL Certificate in. Then, I was able to add <a href="https://en.wikipedia.org/wiki/List_of_DNS_record_types">DNS A record</a> in Route 53 and provide my CloudFront URL there.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/729/1*Z1pdJTGYvDKSCsY7ZoWW6w.png" /><figcaption>Great success :D</figcaption></figure><p>Your safe &amp; fast static webpage is ready! There are just 4 AWS services used for it :)</p><h3>Bonus: CloudFront invalidation</h3><p>What after changing something e.g. in index.html? Putting a new version in S3 is not enough, as CloudFront is cached for a long time.</p><p>In simple scenarios, you can go to your CloudFront distribution and choose “Invalidations” tab there:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5bf7AWztESpfZaSSP7Mf1w.png" /><figcaption>CloudFront Invalidations</figcaption></figure><p><a href="https://medium.com/warsawjs/how-many-aws-services-do-you-need-to-host-a-static-webpage-2-2-aa619fc99fc2">Read part 2/2 here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b811929a9436" width="1" height="1" alt=""><hr><p><a href="https://medium.com/warsawjs/how-many-aws-services-do-you-need-to-host-a-static-webpage-1-2-b811929a9436">How many AWS services do you need to host a static webpage? (1/2)</a> was originally published in <a href="https://medium.com/warsawjs">WarsawJS</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My view on the strategy of Tesla]]></title>
            <link>https://medium.com/@mat3e/my-view-on-the-strategy-of-tesla-51c152ed67ad?source=rss-f9485a48cfa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/51c152ed67ad</guid>
            <category><![CDATA[electric-car]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[elon-musk]]></category>
            <category><![CDATA[tesla]]></category>
            <category><![CDATA[tech]]></category>
            <dc:creator><![CDATA[Mateusz (mat3e)]]></dc:creator>
            <pubDate>Thu, 23 Nov 2017 00:00:00 GMT</pubDate>
            <atom:updated>2017-11-24T15:19:56.668Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*WpLgYYOsBiijTMO9.jpg" /><figcaption><a href="https://en.wikipedia.org/wiki/File:Tesla_Semi_Front.jpg">https://en.wikipedia.org/wiki/File:Tesla_Semi_Front.jpg</a></figcaption></figure><p><em>Originally published at </em><a href="https://www.linkedin.com/pulse/my-view-strategy-tesla-mateusz-chrzonstowski/"><em>https://www.linkedin.com</em></a><em> on November 23, 2017.</em></p><p>After the latest performance of Elon Musk, there are opinions like “Tesla should rather focus on Model 3”, “Tesla is driven by hopes and dreams”, “Tesla has no chance to survive” and so on and so forth.</p><p>I see the point here and I’m aware of the problems including, but not limited to:</p><ul><li><a href="http://www.businessinsider.com/elon-musk-tesla-model-3-cancellations-hamburgers-2017-8?IR=T">400 000 people waiting for Model 3, 60 000 Model 3 cancellations</a></li><li><a href="https://www.wired.com/story/musk-model-3-tesla-production-delays/">Delays when it comes to the production line improvements</a></li><li><a href="https://www.inc.com/suzanne-lucas/tesla-fires-hundreds-of-workers-for-poor-performance.html">Unhappy and fired out employees</a></li><li><a href="https://www.autocar.co.uk/car-news/new-cars/tesla-posts-619-million-loss-third-quarter-2017">Last quarter losses</a></li></ul><p>I also understand people thinking the whole truck and roadster things are to start a new discussion, far away from the real problems. I know articles like:</p><ul><li><a href="https://www.forbes.com/sites/chuckjones/2017/11/13/look-at-the-shiny-semi-truck-to-keep-your-eye-off-the-model-3-problems/#56f3bfa564f5">Look At The Shiny Semi-truck To Keep Your Eye Off The Model 3 Problems</a></li><li><a href="http://bgr.com/2017/11/17/tesla-semi-truck-roadster-launch-analysis-price-release-date/">The 5 biggest questions Tesla didn’t answer last night</a></li></ul><p>All present the valid points.</p><p>Moreover, some researches and engineers argue that Elon overpromised (once again) when it comes to the performance and <a href="https://www.greentechmedia.com/articles/read/tesla-electric-semi-truck-toughest-musk#gs.YOiYIq0">numbers presented by him are just unreal</a>.</p><p>I know all of this, but my article is about a separate thing. I want to point out what are the <strong>good things</strong> about the new cars and how showing them can help e.g. addressing Model 3 issues. I don’t want to focus on whether an electric truck with such a performance can be created or not. I just assume Tesla can do this.</p><p>My personal top 3 arguments for the new cars.</p><h3>1. Creating your own reality</h3><p>All the motivational books I know, have something in common. It is about creating your own reality and pushing bad thoughts out of the head by short and positive sentences, affirmations. This is one of the techniques for making dreams come true. This is for restoring the faith in something. Musk restored faith in Tesla. At least partially.</p><p>I think Barney Stinson nailed this technique in “HIMYM” series:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rPSDNEEYy8ItI0RdWnJkwQ.jpeg" /><figcaption><a href="http://www.imagesbuddy.com/images/74/2013/08/when-im-sad-i-stop-being-sad-and-be-awesome-instead.jpg">http://www.imagesbuddy.com/images/74/2013/08/when-im-sad-i-stop-being-sad-and-be-awesome-instead.jpg</a></figcaption></figure><h3>2. Motivating the employees</h3><p>Long story short: <a href="https://ttmm.io/faith/im-building-a-cathedral/"><em>I’m building a cathedral</em></a>!</p><p>Truck and roadster are shiny new products, which make Tesla great again. At least the hype is back. 500 miles? 1.9 sec? 250+ mph? I think you got the point ;)</p><h3>3. Escaping… to the front</h3><p>What if I told you Tesla is not the first company named after Nikola Tesla, which announced an electric truck? <a href="https://spectrum.ieee.org/cars-that-think/transportation/advanced-cars/electric-truck-startup-nikola-motors-claims-23-billion-preorder-before-prototype-is-even-ready">What if I told you Nikola Motors got 7000 preorders for something which doesn’t even exist as a prototype?</a></p><p><a href="https://www.theverge.com/2017/11/17/16670632/walmart-tesla-semi-truck-preorder">Tesla already got some preorders</a> and something prototype-like was already shown during the event.</p><p>Moreover, Roadster preorders should give the company <a href="https://www.marketwatch.com/story/want-the-new-tesla-roadster-in-2020-prepare-to-pay-tesla-250000-now-2017-11-17">$250 million right now</a>. Sounds good for me…</p><p>I think all this together can help the company survive the hard time. But even a miracle won’t help in the long-term perspective, without having those 5000 cars a week, starting from March 2018.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=51c152ed67ad" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Win-win situation for Microsoft and Amazon]]></title>
            <link>https://medium.com/@mat3e/win-win-situation-for-microsoft-and-amazon-2125c8ded199?source=rss-f9485a48cfa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/2125c8ded199</guid>
            <category><![CDATA[amazon-echo]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[microsoft]]></category>
            <category><![CDATA[amazon]]></category>
            <dc:creator><![CDATA[Mateusz (mat3e)]]></dc:creator>
            <pubDate>Sat, 02 Sep 2017 00:00:00 GMT</pubDate>
            <atom:updated>2017-09-02T20:19:20.485Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/744/0*FFtHwzSQAuEIQeAM.jpg" /><figcaption><a href="https://www.flickr.com/photos/mendhak/4203327202">https://www.flickr.com/photos/mendhak/4203327202</a></figcaption></figure><p><em>Originally published at </em><a href="https://www.linkedin.com/pulse/win-win-situation-microsoft-amazon-mateusz-chrzonstowski"><em>https://www.linkedin.com</em></a><em> on September 2, 2017.</em></p><p>Popular articles appear in the “article waves”. The recent waves were about Google memo and Infosys. Now, it is about the cooperation between Microsoft and Amazon. And I want to be a part of this wave.</p><p>For me, it all started with the article: <a href="https://www.recode.net/2017/8/30/16225140/alexa-cortana-integration-amazon-microsoft-siri-google-assistant"><em>Amazon’s Alexa and Microsoft’s Cortana are going to work together</em></a>. I remember some reports showing Alexa as a market leader, so I was confused after reading this. Is Cortana integration with Microsoft’s applications a real value for Amazon? Is this enough for giving back <a href="https://techcrunch.com/2017/07/03/amazons-alexa-passes-15000-skills-up-from-10000-in-february/">thousands of Alexa skills</a>?</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=%2F%2Fe.infogram.com%2F74b7e223-9574-46b1-acb3-5fabdc10295c%3Fsrc%3Dembed&amp;url=https%3A%2F%2Finfogram.com%2Fvoice-search-assistants-1gl8m3dzvor7p36&amp;image=https%3A%2F%2Fs3-eu-west-1.amazonaws.com%2Finfogram-thumbs-1024%2Fee0626e6-76c0-4b49-ae65-e1be343348b4.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=infogram" width="550" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/5e3ef805034d75f15dd757c26c2365da/href">https://medium.com/media/5e3ef805034d75f15dd757c26c2365da/href</a></iframe><p>Then I took a second look. <a href="https://forums.developer.amazon.com/content/idea/60368/allow-alexaecho-to-use-google-search-engine-instea.html">Bing is already a default search engine for Alexa</a>. Microsoft competes with Amazon rather just in the public cloud area. And it is like <a href="https://www.forbes.com/sites/bobevans1/2017/08/08/10-cloud-acquisitions-amazon-could-make-to-help-jeff-bezos-catch-1-microsoft/#402419f62ea3">Amazon is a leader of IaaS, while Microsoft is good with PaaS and, especially, SaaS</a> (e.g. Office 365). On the other hand, Google and Facebook are/will be Amazon’s direct competitors in <a href="https://www.wired.com/story/google-facebook-online-ad-kings/?mbid=social_twitter_onsiteshare">advertising</a>, <a href="https://www.nytimes.com/2017/08/23/technology/google-walmart-e-commerce-partnership.html?smid=tw-share">shopping</a> and <a href="http://mashable.com/2017/08/11/facebook-watch-wants-your-other-24-hours-a-day/#Ndsjwnj5ksO7">video</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/603/1*z7gJWXxGz5cFMUg-tBAgZw.jpeg" /><figcaption><a href="https://www.srgresearch.com/articles/leading-cloud-providers-continue-run-away-market">https://www.srgresearch.com/articles/leading-cloud-providers-continue-run-away-market</a></figcaption></figure><p>I agree that even just the voice assistants’ cooperation is valuable for both sides. Good summary on this is presented e.g. in the article: <a href="https://www.linkedin.com/pulse/quick-take-why-amazon-microsoft-joining-forces-voice-zach-fuller"><em>Why Amazon And Microsoft Are Joining Forces On Voice</em></a>.</p><p>But it’s not over yet. There is a broader context.</p><p>Microsoft does a favor even in the mentioned cloud area! <a href="https://www.cnbc.com/2017/08/31/microsoft-launches-aws-integrations-for-team-foundation-server-vsts.html">Amazon engineers were supporting Microsoft to integrate its Visual Studio (IDE) with AWS</a>. And something happens in freeware Visual Studio Code as well:</p><h3>Visual Studio Code on Twitter</h3><p>Using @code and deploying Node apps to the cloud? We would love to talk to you...https://t.co/pKxH99EOIA</p><p>For me it looks like a bigger cooperation and a part of a broader strategy.</p><p>And my thoughts? Looking into the crystal ball and <a href="https://www.cnbc.com/2017/08/31/microsoft-windows-10-fall-creators-update-launches-oct-17.html">knowing that the next update of Windows 10 is going to support mixed reality</a>, I’d say that Alexa is a great improvement for Microsoft. And being a part of a mixed reality system can help Amazon with their potential messenger app — <a href="https://recombu.com/mobile/article/amazon-anytime-messenger-app-vs-whatsapp">Anytime</a>. Merging this with another interesting vision, Amazon and Microsoft cooperation may result in <a href="https://medium.com/iotforall/who-will-be-the-ar-vr-social-media-giant-766ea5510ee7">AR social media giant, which would overtake Facebook and Google</a>.</p><p>But even without going so much into the future, we have a win-win situation for both Microsoft and Amazon, at present.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2125c8ded199" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating Angular Dynamic Form with DORF (part II)]]></title>
            <link>https://medium.com/@mat3e/creating-angular-dynamic-form-with-dorf-part-ii-af1693d481bf?source=rss-f9485a48cfa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/af1693d481bf</guid>
            <category><![CDATA[angular2]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[forms]]></category>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Mateusz (mat3e)]]></dc:creator>
            <pubDate>Tue, 29 Aug 2017 20:24:49 GMT</pubDate>
            <atom:updated>2017-08-29T20:52:21.741Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://medium.com/@mat3e/creating-angular-dynamic-form-with-dorf-8456354881f5">First part of the tutorial</a> was a good introduction to <a href="https://www.npmjs.com/package/dorf">DORF</a>, which resulted in the following app (more or less):</p><p><a href="http://embed.plnkr.co/TV4H5K/">DORF QuickStart - part I - Plunker</a></p><h3>Step-by-step</h3><p>Main problems identified <a href="https://medium.com/@mat3e/creating-angular-dynamic-form-with-dorf-8456354881f5">in the first part</a>:</p><ol><li>There are no indicators on the required fields; in our case all the fields are required, but anyway…</li><li>There are 2 buttons visible and just the first one is doing something</li><li>First button is &#39;Save&#39; instead of &#39;Submit&#39;</li><li>update function is not the perfect way of acting with DORF Object</li></ol><h4>Required fields</h4><p>Putting a characteristic red star after the label of the required field is really trivial in DORF. All you need is requiredWithStar set to true somewhere inside DorfModule.forRoot method in app.module.</p><h4>Styling buttons</h4><p>Currently we are having 2 buttons and one of them is not needed. Also, they are ugly. The solution for this — once again — is a modification of DorfModule.forRoot method. The end result can look like this:</p><pre>DorfModule.forRoot({<br>  css: {<br>    section: &#39;row&#39;,<br>    wrapper: &#39;form-group col-12 row&#39;,<br>    label: &#39;col-2 col-form-label&#39;,<br>    fieldGeneralization: &#39;col-10&#39;,<br>    htmlField: &#39;form-control&#39;,<br>    <strong>buttons: {<br>      save: &#39;btn btn-primary&#39;,<br>      reset: &#39;hidden-xs-up&#39;<br>    }</strong><br>  },<br>  dorfFields: [{<br>    tag: DorfField.CHECKBOX,<br>    css: {<br>      wrapper: &#39;checkbox col-12 row&#39;,<br>      htmlField: &#39;checkbox&#39;<br>    }<br>  }],<br>  <strong>requiredWithStar: true</strong><br>})</pre><p>Styles are taken directly from Bootstrap.</p><h4>Changing the buttons</h4><p>Time for something harder. In the current version of DORF, there are no mechanisms for customizing button text. But we can still achieve our goal by:</p><ol><li>Overriding DORF component(s)</li><li>Talking with DORF in a different way</li></ol><p>Let’s take a look at the first option.</p><p><strong>Overriding DORF components</strong></p><p>DORF is written in a modular way. Dependencies are presented below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7AWXCY-ATmfsZqTe9H_qMQ.png" /><figcaption>DORF modules: Core, Fields and a default one</figcaption></figure><p>There are 3 main modules:</p><ol><li>DorfCoreModule — an essence, which exports the configuration, ReactiveFormsModule from Angular and abstract TypeScript classes, used later by the fields.</li><li>DorfFieldsModule — module which collects field-related stuff: <em>input</em>, <em>select</em>, <em>radio</em>, <em>checkbox </em>and the <em>field generalization</em>. The idea behind one module for all the field components is simple — it should allow an easy switch. E.g. it is doable to define components with DORF-like selectors which use e.g. <em>Angular Material</em> behind the scenes. Then, a new module containing them should be used on top of DorfCoreModule. Sooner or later DORF should be improved to allow even an easier way for overriding the default fields.</li><li>DorfModule — final module, which uses the previous ones and adds wrappers and buttons.</li></ol><p>As written above, DorfModule stores buttons component. Let’s take a deeper look at this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/972/1*k0GiQSinH0xCe0lFGd4Fiw.png" /><figcaption>The structure of DorfModule</figcaption></figure><p>What needs to be done is similar to what happened in definition-extras example from the official DORF repository. DorfButtonsComponent has HTML template which is the source of our problem. And the solution is to create a new component, e.g. src/app/ext/custom-buttons-component.ts:</p><pre>import { Component } from &#39;@angular/core&#39;;<br>import { DorfButtonsComponent } from &#39;dorf&#39;;</pre><pre>@Component({<br>    <strong>selector: &#39;dorf-buttons&#39;,</strong><br>    template: `<br>    &lt;section [ngClass]=&quot;config.css.buttons?.group&quot;&gt;<br>        &lt;button (click)=&quot;submit()&quot; [ngClass]=&quot;config.css.buttons?.save&quot; [disabled]=&quot;!form || !form.valid&quot;&gt;<strong>Submit</strong>&lt;/button&gt;<br>    &lt;/section&gt;<br>    `<br>})<br>export class CustomButtonsComponent <strong>extends DorfButtonsComponent</strong> { }</pre><p>HTML was modified to match our requirements. We even removed unneeded “Reset” button. Hints:</p><ul><li>The selector has to match the original selector</li><li>It may be useful to extend the original component</li></ul><p>New component should be registered in the module:</p><pre>import { BrowserModule } from &#39;<a href="http://twitter.com/angular/platform-browser">@angular/platform-browser</a>&#39;;<br>import { NgModule } from &#39;<a href="http://twitter.com/angular/core">@angular/core</a>&#39;;<br>import { FormsModule } from &#39;<a href="http://twitter.com/angular/forms">@angular/forms</a>&#39;;<br>import { HttpModule } from &#39;<a href="http://twitter.com/angular/http">@angular/http</a>&#39;;</pre><pre>import { <br>  <strong>DorfFieldsModule</strong>,<br>  DorfField,<br>  <strong>DorfFieldWrapperComponent,<br>  DorfGroupWrapperComponent</strong><br>} from &#39;dorf&#39;;</pre><pre><strong>import { CustomButtonsComponent } from &#39;./ext/custom-buttons-component&#39;;</strong></pre><pre>import { UserFormComponent } from &#39;./user/user-form.component&#39;;<br>import { AppComponent } from &#39;./app.component&#39;;</pre><pre>@NgModule({<br>  declarations: [<br>    UserFormComponent,<br>    AppComponent,<strong><br>    CustomButtonsComponent,<br>    DorfFieldWrapperComponent,<br>    DorfGroupWrapperComponent</strong><br>  ],<br>  imports: [<br>    BrowserModule,<br>    FormsModule,<br>    HttpModule,<br>    <strong>DorfFieldsModule</strong>.forRoot({<br>      css: {<br>        section: &#39;row&#39;,<br>        wrapper: &#39;form-group col-12 row&#39;,<br>        label: &#39;col-2 col-form-label&#39;,<br>        fieldGeneralization: &#39;col-10&#39;,<br>        htmlField: &#39;form-control&#39;,<br>        <strong>buttons: {<br>          save: &#39;btn btn-primary&#39;<br>        }</strong><br>      },<br>      dorfFields: [{<br>        tag: DorfField.CHECKBOX,<br>        css: {<br>          wrapper: &#39;checkbox col-12 row&#39;,<br>          htmlField: &#39;checkbox&#39;<br>        }<br>      }],<br>      requiredWithStar: true<br>    })<br>  ],<br>  providers: [],<br>  bootstrap: [AppComponent]<br>})<br>export class AppModule { }</pre><p>Note that we switched from DorfModule to DorfFieldsModule, so it was needed to register DorfFieldWrapperComponent and DorfGroupWrapperComponent “manually”.</p><p>The end result for this part is available here: <a href="http://embed.plnkr.co/38WWfdqRICzB4zlzmKon/">http://embed.plnkr.co/38WWfdqRICzB4zlzmKon/</a></p><p><strong>Talking with DORF in a different way</strong></p><p>Overriding DORF pieces is a powerful technique, but it is too much in our case. Let’s undo the last changes and modify DorfForm decorator on UserFormComponent:</p><pre>@DorfForm({<br>  renderWithoutButtons: true<br>})</pre><p>Then, let’s add &lt;button class=&quot;btn btn-primary&quot;&gt;Submit&lt;/button&gt; manually to the template of AppComponent.</p><h4>A better way of acting with DORF Object</h4><p>What if I told you that you can use DORF and enjoy the [(ngModel)]-like experience? Let’s start the modification with removing the update function from our model. Then, for every field we want an immediate updating, we have to add updateModelOnChange: true option:</p><pre>@DorfObject()<br>export class User {<br>  @DorfInput({<br>    label: &#39;Username&#39;,<br>    type: &#39;input&#39; as InputType,<br>    validator: Validators.required,<br>    <strong>updateModelOnChange: true</strong><br>  })<br>  private _login: string;</pre><pre>  @DorfInput({<br>    label: &#39;Password&#39;,<br>    type: &#39;password&#39; as InputType,<br>    validator: Validators.required,<br>    <strong>updateModelOnChange: true</strong><br>  })<br>  private _password: string;</pre><pre>  @DorfCheckbox({<br>    innerLabel: &#39;I accept the terms and conditions&#39;,<br>    validator: Validators.requiredTrue,<br>    <strong>updateModelOnChange: true</strong><br>  })<br>  private _acceptance: boolean;</pre><pre>  constructor(options?: IUser) {<br>    if (options) {<br>      this._login = options._login;<br>      this._password = options._password;<br>      this._acceptance = options._acceptance;<br>    }<br>  }</pre><pre>  get login() { return this._login; }<br>  get password() { return btoa(this._password); }<br>  get acceptance() { return this._acceptance; }</pre><pre>  get basicAuth() {<br>    if (this._login &amp;&amp; this._password) {<br>      return btoa(`${this._login}:${this._password}`);<br>    }<br>  }<br>}</pre><p>Bonus: you can specify debounce parameter, to delay an update. It expects a number of milliseconds as a value. It is similar to one of ngModelOptions parameter from <a href="https://docs.angularjs.org/api/ng/directive/ngModelOptions">Angular 1.3</a>.</p><p>That’s it. Having such updating, it is possible to consume user directly in AppComponent.</p><h4>Recap</h4><p>We fulfilled all the requirements from the previous part and extended our DORF knowledge:</p><ol><li>DorfModule.forRoot method allows not only assigning CSS classes to fields, but also to buttons; it also has additional parameters, e.g. for setting a red star on the required fields</li><li>DORF is modular and its components can be overridden pretty easily</li><li>DORF allows for [(ngModel)]-like updating. Behind the scenes, immediate updating uses events, so it is a reactive way, not a two-way binding</li></ol><p>Finished app is presented here:</p><p><a href="http://embed.plnkr.co/0LqHQa/">Angular DORF QuickStart - part II, finished - Plunker</a></p><h3>The future</h3><p>DORF is still under the development, but its code already allows for handling plenty of use cases and scenarios, which are not yet presented in tutorials.</p><h4>Planned tutorials</h4><ul><li>Advanced options and further overriding of DORF components</li><li>Nested objects and a column layout</li><li>Adding custom fields</li><li>Testing DORF</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af1693d481bf" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating Angular Dynamic Form with DORF]]></title>
            <link>https://medium.com/@mat3e/creating-angular-dynamic-form-with-dorf-8456354881f5?source=rss-f9485a48cfa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/8456354881f5</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Mateusz (mat3e)]]></dc:creator>
            <pubDate>Fri, 11 Aug 2017 15:17:13 GMT</pubDate>
            <atom:updated>2017-08-29T20:25:58.146Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://github.com/mat3e/dorf">DORF (Domain Object Reactive Forms)</a> is a library for Angular, which speeds up the creation of <em>Dynamic Forms</em>.</p><h3>Introduction</h3><p>First part of DORF QuickStart tutorial covers the following topics:</p><ul><li>what is the target form structure,</li><li>how to use CSS libraries together with DORF,</li><li>how to play with basic DORF annotations</li></ul><h4>Prerequisites</h4><p>It may be useful to read the following tutorials on Angular:</p><ul><li><a href="https://angular.io/guide/reactive-forms">Reactive Forms</a></li><li><a href="https://angular.io/guide/dynamic-form">Dynamic Forms</a></li></ul><p>The latter from the list was a direct inspiration for DORF.</p><h4>What does Domain Object mean?</h4><p>Library has to have a catchy name and DORF sounds better than ORF (only Germans are allowed to disagree :)). The term is taken from the Domain Driven Design approach (DDD), where system is divided into separate parts (domains). It’s not like every object in the system should have its own form. It is needed for the selected, <em>main</em> ones. And those can be called Domain Objects even if the architecture is not DDD.</p><h3>Step-by-step</h3><p>We are going to create a simple form, getting to know DORF better and better with each step.</p><h4>Starting point</h4><p>In order to start we should generate/download an app according to <a href="https://angular.io/guide/quickstart">Angular QuickStart</a>.<br>Then it is needed to install DORF, e.g. by using npm install dorf --save command.</p><h4>CSS library</h4><p>DORF is very configurable. Especially when it comes to the CSS classes. From the beginning, the main idea was to leave a choose of CSS framework to the end library user.</p><p>For the tutorial let’s choose <a href="http://v4-alpha.getbootstrap.com/">Bootstrap</a>, while the library’s GitHub examples use rather <a href="https://purecss.io/">Pure</a>. It is enough to include just CSS part from the library, so the changed index.html can look like this:</p><pre>&lt;!doctype html&gt;<br>&lt;html&gt;<br><br>&lt;head&gt;<br>  &lt;meta charset=&quot;utf-8&quot;&gt;<br>  &lt;title&gt;DORF App&lt;/title&gt;<br>  &lt;base href=&quot;/&quot;&gt;<br><br>  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;<br>  &lt;link rel=&quot;icon&quot; type=&quot;image/x-icon&quot; href=&quot;favicon.ico&quot;&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://unpkg.com/bootstrap@4.0.0-alpha.6/dist/css/bootstrap.min.css&quot;&gt;<br>&lt;/head&gt;<br><br>&lt;body&gt;<br>  &lt;app-root&gt;Loading...&lt;/app-root&gt;<br>&lt;/body&gt;<br><br>&lt;/html&gt;</pre><h4>Example requirements</h4><p>DORF can be imported in a way, which matches our needs. Let’s keep things simple and define the following requirements:</p><ol><li>Form for the user (login, password, acceptance of terms and conditions)</li><li>1 field per line</li><li>Label and field in the same line as <a href="https://v4-alpha.getbootstrap.com/components/forms/#textual-inputs">here</a></li><li>Checkbox with just one label as <a href="https://v4-alpha.getbootstrap.com/components/forms/#disabled-states">here</a></li><li>1 button for submitting the form</li></ol><h4>DORF output</h4><p>To understand how to configure CSS in DORF, let’s take a look at the skeleton of the form generated by the library:</p><pre>&lt;dorf-form-component&gt;                                    <br>  &lt;form class=&quot;form&quot;&gt;                                    <br>    &lt;fieldset class=&quot;fieldset&quot;&gt;&lt;!-- optional --&gt;         <br>      &lt;section class=&quot;section&quot;&gt;                          <br>        &lt;dorf-field-wrapper class=&quot;wrapper&quot;&gt;&lt;!--...--&gt;&lt;/dorf-field-wrapper&gt;<br>        &lt;dorf-field-wrapper class=&quot;wrapper&quot;&gt;&lt;!--...--&gt;&lt;/dorf-field-wrapper&gt;<br>        &lt;!-- ... --&gt;<br>      &lt;/section&gt;<br>      &lt;dorf-group-wrapper&gt;&lt;!--...--&gt;&lt;/dorf-group-wrapper&gt;<br>      &lt;dorf-group-wrapper&gt;&lt;!--...--&gt;&lt;/dorf-group-wrapper&gt;<br>      &lt;section class=&quot;section&quot;&gt;<br>        &lt;!--...--&gt;<br>      &lt;/section&gt;<br>      &lt;!-- ... --&gt;<br>    &lt;/fieldset&gt;<br>    &lt;dorf-buttons&gt;&lt;!--...--&gt;&lt;/dorf-buttons&gt;<br>  &lt;/form&gt;<br>&lt;/dorf-form-component&gt;</pre><p>In general:</p><ol><li>dorf-form-component - Angular component created by the library consumer to manage the form</li><li>form - standard HTML element; first place where classes can be set during importing DORF module (form property)</li><li>fieldset - optional parameter. Visible when renderFieldsetAroundFields set to true inside @DorfForm annotation. CSS classes for this can be set when importing DORF module (fieldset property). This main fieldset doesn&#39;t contain any legend (unlike the fieldset from dorf-group-wrapper)</li><li>section - HTML element; it is always around dorf-field-wrapper elements. When importing DORF module, there is a columnsNumber property which defines how many dorf-field-wrapper elements should be inside each section. Section CSS classes can by set when importing DORF module (section property)</li><li>dorf-field-wrapper - DORF component which &quot;wraps&quot; the field context. It stores label, field and the error message. It is described in detail later. CSS classes for this component can be assigned in many places, but always with a wrapper property</li><li>dorf-group-wrapper - another DORF component, used when nesting DORF Objects. We are not going to use this in this tutorial and CSS classes cannot be assigned directly at its level anyway</li><li>dorf-buttons - DORF component for storing form buttons. When importing DORF module, there is renderWithoutButtons property and when it is set to true, dorf-buttons won&#39;t be presented. CSS classes cannot be set directly on the component, but later, within its body</li></ol><p><strong>The output of </strong><strong>dorf-field-wrapper</strong></p><p>The content of dorf-field-wrapper looks like this:</p><pre>&lt;dorf-field-wrapper class=&quot;wrapper&quot;&gt;<br>  &lt;label class=&quot;label&quot;&gt;...&lt;/label&gt;<br>  &lt;dorf-field class=&quot;fieldGeneralization&quot;&gt;<br>    &lt;dorf-input class=&quot;dorfField&quot;&gt;&lt;!--...--&gt;&lt;/dorf-input&gt;<br>    &lt;dorf-radio class=&quot;dorfField&quot;&gt;&lt;!--...--&gt;&lt;/dorf-radio&gt;<br>    &lt;dorf-select class=&quot;dorfField&quot;&gt;&lt;!--...--&gt;&lt;/dorf-select&gt;<br>    &lt;dorf-checkbox class=&quot;dorfField&quot;&gt;&lt;!--...--&gt;&lt;/dorf-checkbox&gt;<br>    &lt;!--...--&gt;<br>  &lt;/dorf-field&gt;<br>  &lt;div class=&quot;error&quot;&gt;...&lt;/div&gt;<br>&lt;/dorf-field-wrapper&gt;</pre><p>In short words:</p><ol><li>label and error are within standard HTML elements. CSS classes for them can be set thanks to label and error properties</li><li>dorf-field is a DORF component which allows operating on fields without going into detail. It stores both out of the box fields and the custom ones, added with dorfFields property when importing DORF module. At the end only one of the fields listed within dorf-field body is presented. Therefore the good way of thinking about this component is &quot;field generalization&quot;. Therefore CSS classes can be assigned to this, with a fieldGeneralization property</li><li>dorf-input, dorf-radio, dorf-select, dorf-checkbox - out of the box DORF components. Each one represents a different HTML field. As mentioned above, only one of them would be presented under the dorf-field under the concrete conditions. It is possible to assign CSS classes at this level with dorfField property</li></ol><p>DORF is written in a very modular way, that’s why each field is defined by its own component.</p><p><strong>The output of different out of the box fields</strong></p><p>We can divide out of the box fields into 2 groups: those which support additional labeling and those which don’t. Knowing HTML, you can guess that dorf-checkbox and dorf-radio are supporting additional labeling (inner label).</p><p>Inner label means here that we have a label around the field. Let’s take a look at the simplified content of dorf-radio:</p><pre>&lt;label *ngFor class=&quot;innerLabel&quot;&gt;<br>  &lt;input type=&quot;radio&quot; class=&quot;htmlField&quot;&gt; ...<br>&lt;/label&gt;</pre><p>Each option is wrapped with the label. Label can have CSS classes, defined by an innerLabel property. Options are standard HTML input elements which can have CSS classes assigned with htmlField property. Worth mentioning that innerLabel is independent from label underneath dorf-field-wrapper, so it is possible to have 2 labels, to have just a chosen one or to not have any at all.</p><p>On the other hand, dorf-select and dorf-input don&#39;t support inner labels. Simplified template of dorf-input looks like this:</p><pre>&lt;input class=&quot;htmlField&quot; /&gt;</pre><p>Nothing fancy :) once again, htmlField property is strictly connected with the HTML representation of the form field.</p><p><strong>The output of </strong><strong>dorf-buttons</strong></p><p>The last DORF component is pretty simple when it comes to its body:</p><pre>&lt;section class=&quot;group&quot;&gt;<br>  &lt;button class=&quot;save&quot;&gt;Save&lt;/button&gt;<br>  &lt;button class=&quot;reset&quot;&gt;Reset&lt;/button&gt;<br>&lt;/section&gt;</pre><p>There are 2 predefined buttons, grouped within the section HTML element. CSS classes can be assigned to them thanks to group, save and reset properties.</p><h4>Initial configuration</h4><p>From the requirements we can figure out that just input and checkbox fields should be used. When configuring CSS classes, it is good to have as much as possible at the general level and override just a couple of styles at the field level. Then, in rare cases, everything can be overriden at the definition level. DORF approach to CSS is similar to the well-known browser one - the closer the element, the more likely to be assigned.</p><p>At the end app.module can look like this:</p><pre>import { BrowserModule } from &#39;@angular/platform-browser&#39;;<br>import { NgModule } from &#39;@angular/core&#39;;<br>import { FormsModule } from &#39;@angular/forms&#39;;<br>import { HttpModule } from &#39;@angular/http&#39;;<br><br>import { DorfModule, DorfField } from &#39;dorf&#39;;<br><br>import { AppComponent } from &#39;./app.component&#39;;<br><br>@NgModule({<br>  declarations: [<br>    AppComponent<br>  ],<br>  imports: [<br>    BrowserModule,<br>    FormsModule,<br>    HttpModule,<br>    DorfModule.forRoot({<br>      css: {<br>        section: &#39;row&#39;,<br>        wrapper: &#39;form-group col-12 row&#39;,<br>        label: &#39;col-2 col-form-label&#39;,<br>        fieldGeneralization: &#39;col-10&#39;,<br>        htmlField: &#39;form-control&#39;<br>      },<br>      dorfFields: [{<br>        tag: DorfField.CHECKBOX,<br>        css: {<br>          wrapper: &#39;checkbox col-12 row&#39;,<br>          htmlField: &#39;checkbox&#39;<br>        }<br>      }]<br>    })<br>  ],<br>  providers: [],<br>  bootstrap: [AppComponent]<br>})<br>export class AppModule { }</pre><p>Importing DorfModule at the beginning is needed in order to use it under the imports module property. Then, the configuration is done by executing forRoot static method on the module level and passing IDorfService object as a parameter. Many things are defined at the general, css level. CSS classes are taken from the Bootstrap examples and mapped according to the knowledge about the rendering:</p><ul><li>each section should be a separate block element (&#39;row&#39;),</li><li>something, which groups field and label (wrapper) should be both &#39;form-group&#39; and &#39;row&#39;; it is already under the &#39;row&#39;, so we should add &#39;col-12&#39; at this level as well,</li><li>in order to have label and field in the same line, &#39;col-&#39; classes should be assigned (to label and to fieldGeneralization),</li><li>htmlField got &#39;form-control&#39; class</li></ul><p>The only exception from those patterns is dorf-checkbox. In order to assign CSS classes just to this kind of field (and override the previous classes if exist), dorfFields array is used. It can change existing fields and/or add new ones. tag property is the required key for elements in this array (in our case key was taken from imported DorfField class).</p><h4>Model for the form</h4><p>For the simple requirements we have here, there is a simple model to be created. It’s a good idea to start with a “contract”. Let’s create a file src/app/user/model.ts with a following interface inside:</p><pre>export interface IUser {<br>  _login: string;<br>  _password: string;<br>  _acceptance: boolean;<br>}</pre><p>Interface defines what will be returned from our form. Interface properties have to match the future annotated <em>Domain Object</em> class properties. Let’s create a class now and enrich it with a constructor, consuming the interface. Let’s act as guys who care about the security (the usage of btoa and stuff):</p><pre>export class User {<br>  private _login: string;<br>  private _password: string;<br>  private _acceptance: boolean;<br><br>  constructor(options?: IUser) {<br>    if (options) {<br>      this._login = options._login;<br>      this._password = options._password;<br>      this._acceptance = options._acceptance;<br>    }<br>  }<br><br>  update(options?: IUser) {<br>    if (options) {<br>      this._login = options._login;<br>      this._password = options._password;<br>      this._acceptance = options._acceptance;<br>    }<br>  }<br><br>  get login() { return this._login; }<br>  get password() { return btoa(this._password); }<br>  get acceptance() { return this._acceptance; }<br><br>  get basicAuth() {<br>    if (this._login &amp;&amp; this._password) {<br>      return btoa(`${this._login}:${this._password}`);<br>    }<br>  }<br>}</pre><p>Model is almost ready. The last part is to make it DORF! The final shape of model.ts can look like this:</p><pre>import { Validators } from &#39;@angular/forms&#39;;<br>import { DorfObject, InputType, DorfInput, DorfCheckbox } from &#39;dorf&#39;;<br><br>export interface IUser {<br>  _login: string;<br>  _password: string;<br>  _acceptance: boolean;<br>}<br><br>@DorfObject()<br>export class User {<br>  @DorfInput({<br>    label: &#39;Username&#39;,<br>    type: &#39;input&#39; as InputType,<br>    validator: Validators.required<br>  })<br>  private _login: string;<br><br>  @DorfInput({<br>    label: &#39;Password&#39;,<br>    type: &#39;password&#39; as InputType,<br>    validator: Validators.required<br>  })<br>  private _password: string;<br><br>  @DorfCheckbox({<br>    innerLabel: &#39;I accept the terms and conditions&#39;,<br>    validator: Validators.requiredTrue<br>  })<br>  private _acceptance: boolean;<br><br>  constructor(options?: IUser) {<br>    if (options) {<br>      this._login = options._login;<br>      this._password = options._password;<br>      this._acceptance = options._acceptance;<br>    }<br>  }<br><br>  update(options?: IUser) {<br>    if (options) {<br>      this._login = options._login;<br>      this._password = options._password;<br>      this._acceptance = options._acceptance;<br>    }<br>  }<br><br>  get login() { return this._login; }<br>  get password() { return btoa(this._password); }<br>  get acceptance() { return this._acceptance; }<br><br>  get basicAuth() {<br>    if (this._login &amp;&amp; this._password) {<br>      return btoa(`${this._login}:${this._password}`);<br>    }<br>  }<br>}</pre><p>It is OK to put DORF annotations on the private fields. It is a property name which matters here, not an access modifier. And the above piece of code, should prove that DORF is about <em>Model-driven forms within the model</em>.</p><h4>Form component</h4><p>To finalize the app, we need just one more piece from the Angular library — component which consumes DorfObject. Here is the example code of user-form.component.ts from src/app/user/ directory:</p><pre>import { Component, Output, EventEmitter } from &#39;@angular/core&#39;;<br>import { IDorfForm, DorfForm, DorfObjectInput, DorfConfigService } from &#39;dorf&#39;;<br><br>import { IUser, User } from &#39;./model&#39;;<br><br>@DorfForm()<br>@Component({<br>  selector: &#39;app-user-form&#39;<br>})<br>export class UserFormComponent implements IDorfForm {<br>  @DorfObjectInput() user: User;<br><br>  constructor(public config: DorfConfigService) { }<br><br>  onDorfSubmit() {<br>    this.user.update(this[&#39;form&#39;].value as IUser);<br>  }<br>}</pre><p>A couple of things worth mentioning:</p><ol><li>DorfForm is a special annotation, which should be placed over Component annotation; if Component has no template nor templateUrl, then DorfForm generates the template for us! DorfForm can consume an interface with 3 options: additionalTags, renderFieldsetAroundFields and renderWithoutButtons</li><li>IDorfForm is a helper interface, something like e.g. OnChange from Angular which forces us to have DorfConfigService somewhere inside the component</li><li>DorfObjectInput works like Angular Input, but should be used once within the component in order to point out an object marked as DorfObject previously</li><li>DorfConfigService is needed within the component; it should be injected and used in the constructor e.g. to disable all the fields</li><li>onDorfSubmit is a special method, connected with DORF save button from dorf-buttons; this[&#39;form&#39;].value is the way of getting an object with actual form values (which can be casted to IUser in our case)</li></ol><p>UserFormComponent has to be presented inside the main module declarations array.</p><h4>Polishing the app</h4><p>At the end of the first iteration, we should update AppComponent:</p><pre>import { Component } from &#39;@angular/core&#39;;<br><br>import { User } from &#39;./user/model&#39;;<br><br>@Component({<br>  selector: &#39;app-root&#39;,<br>  templateUrl: &#39;./app.component.html&#39;,<br>  styleUrls: [&#39;./app.component.css&#39;]<br>})<br>export class AppComponent {<br>  title = &#39;My DORF App&#39;;<br><br>  // object to be passed to the form<br>  user: User = new User();<br>}</pre><p>And its HTML:</p><pre>&lt;main class=&quot;container&quot;&gt;<br>  &lt;h1&gt;<br>    {{title}}<br>  &lt;/h1&gt;<br><br>  &lt;app-user-form [user]=&quot;user&quot;&gt;&lt;/app-user-form&gt;<br><br>  &lt;!-- the evidence that the user has changed --&gt;<br>  &lt;hr&gt; Basic {{user.basicAuth}}<br>&lt;/main&gt;</pre><h4>Recap</h4><p>First version is ready. It can be run with npm start command and verified on <em>localhost:4200</em>. Things to be improved (<a href="https://medium.com/@mat3e/creating-angular-dynamic-form-with-dorf-part-ii-af1693d481bf">in the second part of the tutorial</a>):</p><ol><li>There are no indicators on the required fields; in our case all the fields are required, but anyway…</li><li>There are 2 buttons visible and just the first one is doing something</li><li>First button is &#39;Save&#39; instead of &#39;Submit&#39;</li><li>update function is not the perfect way of acting with DORF Object</li></ol><h3>The future</h3><p>DORF is still under the development, but its code already allows for handling plenty of use cases and scenarios, which are not yet presented in tutorials.</p><h4>Planned tutorials</h4><ul><li>Advanced options and overriding DORF components</li><li>Nested objects and a column layout</li><li>Adding custom fields</li><li>Testing DORF</li></ul><p><em>Originally published at </em><a href="https://mat3e.github.io/dorf/"><em>mat3e.github.io</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8456354881f5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Are programmers safe from automation?]]></title>
            <link>https://medium.com/@mat3e/are-programmers-safe-from-automation-9246fc1aa525?source=rss-f9485a48cfa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/9246fc1aa525</guid>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Mateusz (mat3e)]]></dc:creator>
            <pubDate>Sun, 30 Jul 2017 00:00:00 GMT</pubDate>
            <atom:updated>2023-06-10T17:06:12.834Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/512/0*tT3Qs2Hlpss9qJ8s.png" /><figcaption><a href="https://www.linkedin.com/pulse/ai-deep-learning-explained-simply-fabio-ciucci">James Bridle entraps a self-driving car</a></figcaption></figure><p>I’m a software developer with a hands-on experience in various technologies, from back-end to front-end, including an integration layer. And, as other developers, I’m witnessing changes in the world of code.</p><h3>Changes, changes, changes</h3><p>2014–2015 I was a proud user of <em>TypeScript</em> and <em>AngularJS</em> combo. Then, I had like 12-month break from the front-end and came back to this in 2016. What can I say? I just agree with <a href="https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f">this article</a>. It changed…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/811/1*EmUVqTvo69Sh7Kqws7F_Fw.png" /><figcaption><a href="https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f">https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f</a></figcaption></figure><p>Technologies are always first to be changed, but it is not only about switching from language A to language B. Not even about new frameworks/libraries. Problems are even with the official versions of the languages. A couple of examples:</p><ul><li>I used to know <em>C++</em> (no professional experience, but still). And I recently took a look at its <a href="https://en.wikipedia.org/wiki/C%2B%2B14#Generic_lambdas">Wikipedia description</a>. I realized I don’t know it anymore. I don’t even know <em>C++11</em>, while <em>C++17</em> is already presented.</li><li>At some point in time <a href="http://www.networkworld.com/article/2920183/microsoft-subnet/mark-your-calendar-java-9-finally-has-a-release-date.html">there were plans to introduce <em>Java 9</em> just 2 years after <em>Java 8</em></a>. And from version 7, its evolution is pretty dynamic.</li><li><em>JavaScript</em> specification, <em>ECMAScript</em>, has now an <a href="https://bytearcher.com/articles/es6-vs-es2015-name/">alternative versioning convention</a> to point out yearly updates. The newest version is <em>ES2017</em>.</li></ul><p>All those syntax changes in programming languages are not the results of authors’ fantasies. In my opinion, those are just obligatory things in the <em>IoT</em>, containerization, cloud computing and <em>Microservices</em> era. It is needed to support asynchronous communication to process massive data and asynchronous communication is usually implemented with promises/observables and those usually consume functions, so programming languages start including lambda expressions. Containers enforce modularization, so programming languages start moving into modularization. And so on and so forth.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*7A7fy3AE0segc1PG0va2qA.gif" /><figcaption><a href="http://www.dilbert.com/strip/2017-05-15">http://www.dilbert.com/strip/2017-05-15</a></figcaption></figure><p>OK, we got it. But, what are the trends? What is the direction? My answer is automation. We are moving into the declarative programming. I see 2 things which become more and more popular:</p><ol><li>Annotations and “behind the scenes” approach,</li><li>Functional programming.</li></ol><h3>Annotations and “behind the scenes” approach</h3><p>I’ve mentioned <em>Microservices Pattern</em>. With this pattern, IT architects should focus on the cooperation between the small applications. Focus is moved to the higher level of abstraction. Every service is declaring its functionalities within the contract and that’s it. Scalability, fast time-to-market and technology independence are the main advantages here [<a href="https://dzone.com/articles/microservices-in-practice-1">source</a>].</p><p>And contracts are presented at the lower, programmer’s level as well:</p><ul><li>Popular <em>Java</em> frameworks, like <em>Spring</em> and <em>Hibernate</em> have XML configuration/contracts for a long time. Nowadays they support also configuration by annotations. And this works also for the front-end world. <em>Angular</em> is the evidence here.</li><li>Annotations are not only for configuring. The less lines of the written code, the less bugs in the code. Annotations in <a href="https://projectlombok.org/"><em>Lombok</em></a>, <em>AsspectJ</em>, <em>Spring AOP</em> and <a href="https://github.com/OpenFeign/feign"><em>Feign</em></a> literally generate the code for us. And a related topic are things like <em>Spring Repositories</em>, which require just method names and the implementation happens <strong>automagically</strong>.</li><li>Declarative/contracts approach is presented in <a href="http://start.spring.io/"><em>Spring Boot</em></a>, which is a mechanism for getting a preconfigured app (with all the libraries in their proper versions) based on our choices.</li><li>Declarative/contracts approach is presented in all the <em>CLI</em> tools and code generators like: <a href="https://cli.angular.io/">Angular CLI</a>, <a href="http://yeoman.io/">Yeoman</a> or <a href="https://jhipster.github.io/">JHipster</a>.</li></ul><p>You declare <strong>what</strong> and it just happens. It is already here, especially for data model and UI (forms, views etc.).</p><h3>Functional programming</h3><p>On the other hand, we can observe the functional programming (r)evolution. One step forward from <em>Microservices</em> resulted in <em>Serverless Architecture</em>. <a href="https://serverless.zone/an-abstracted-serverless-microservices-architecture-33706fabc516">There is a following way of thinking</a>: “ <em>Microservice</em> shouldn’t do much, but should do it perfectly, so why not converting it into a single function?”.</p><p>Functions make sense, because we are using verbs at a daily basis to clarify our intentions. Just try to describe your morning routine without using verbs. In Polish language, we have even a differentiation between a “sentence” and the “equivalent of a sentence”. In short words — you cannot tell the “sentence” without verbs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/463/1*gZZClFP5R7qcoC52tVJuWg.png" /><figcaption><a href="https://twitter.com/sempf/status/859909118361993216/photo/1">https://twitter.com/sempf/status/859909118361993216/photo/1</a></figcaption></figure><p>Core Java way of evolution is enough for me to accept this functional trend. Non-trivial business logic would be always described by verbs: “ calculate a premium (<strong>add</strong> this, <strong>multiply</strong> by this, <strong>subtract</strong> that)”, “ <strong>verify</strong> the customer (e.g. <strong>check</strong> his shopping history)” and so on [<a href="https://medium.com/@PaulDJohnston/what-is-serverless-architecture-43b9ea4babca">similar opinion</a>].</p><p>I believe that this functional thing can also be automated. <a href="https://fossbytes.com/microsoft-ai-system-deepcoder/">Microsoft has already created AI which is able to code</a>. Sooner or later it should be possible for such AI to code every simple function and then it would be a matter of dividing system into fine-grained functions in order to implement it.</p><p>Simple functions and contracts and we are done.</p><h3>The programmers of tomorrow</h3><p>I really see the world, where machines overtake people’s jobs. But, <a href="http://www.bbc.co.uk/news/technology-34066941">unlike in some reports</a>, in my vision programmers are NOT safe from the automation. The automation already started. Every time someone uses <em>JHipster</em> or <em>Spring Boot</em>, they move closer to the full automation.</p><p>The only thing programmers (including me) can do, is to adapt. You can sit and cry that escalator makes you fat, but it would be better to use it to walk faster instead. Thanks to the automation, programmers would be able to take a responsibility for more ambitious tasks. Programmers could become real human-machine translators. Without spending too much time on the implementation details, being sure the code follows all the best practices at the same time.</p><p>But I’m referring here to the ambitious programmers, not to the ordinary “coders”, who currently earn a lot of money, while they do nothing but copying and pasting to create yet another similar thing (a part of the UI, an entity, a logging functionality, a process, etc.). Such coders are going to be fully replaced by the <strong>machines</strong>. Sooner or later.</p><p>But there is a light of hope, even for such coders. Having all the automation, software should be developed faster and cheaper. And it should result in more systems in general. More systems require more testers, because each application, even the one created by the machines, would be used by the end users, humans in most cases. And testers are humans as well. I see the ordinary coders as the future “technical testers”, who are able to do small fixes and a tiny customization of an app.</p><p>So even a big automation doesn’t scare me. I see more advantages than disadvantages here. Either a more ambitious work or new job positions (for less ambitious guys). And a faster time-to-market for everyone. But when? This is a separate topic…</p><p>And you, what do you think? Are programmers safe from automation?</p><p><em>Originally published at </em><a href="https://www.linkedin.com/pulse/programmers-safe-from-automation-mateusz-chrzonstowski"><em>https://www.linkedin.com</em></a><em> on July 30, 2017.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9246fc1aa525" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>