{"id":2085,"date":"2024-06-19T15:09:25","date_gmt":"2024-06-19T22:09:25","guid":{"rendered":"https:\/\/www.angulartraining.com\/daily-newsletter\/?p=2085"},"modified":"2024-06-19T15:09:26","modified_gmt":"2024-06-19T22:09:26","slug":"tutorial-architecting-forms-with-signals","status":"publish","type":"post","link":"https:\/\/www.angulartraining.com\/daily-newsletter\/tutorial-architecting-forms-with-signals\/","title":{"rendered":"Tutorial: Architecting forms with Signals"},"content":{"rendered":"\n<p>In today&#8217;s post, I want to showcase several Angular framework features in one example. More specifically, we&#8217;ll use <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/what-are-standalone-components\/\" target=\"_blank\" rel=\"noopener\" title=\"\">standalone components<\/a>, signals with <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/model-for-signal-based-2-way-data-bindings\/\" target=\"_blank\" rel=\"noopener\" title=\"\">model()<\/a> and <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/model-for-signal-based-2-way-data-bindings\/\" target=\"_blank\" rel=\"noopener\" title=\"\">input()<\/a>, as well as <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/angular\/forms\/\" target=\"_blank\" rel=\"noopener\" title=\"\">forms<\/a>.<\/p>\n\n\n\n<p>Our goal is to build a reusable date-range picker component  to select two dates:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"356\" height=\"87\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-1.png\" alt=\"\" class=\"wp-image-2086\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-1.png 356w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-1-300x73.png 300w\" sizes=\"auto, (max-width: 356px) 100vw, 356px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>To do so, let&#8217;s create a standalone component with two HTML date inputs (<a href=\"https:\/\/blog.angulartraining.com\/how-to-pick-the-right-dependencies-for-your-angular-application-328ce637b982\" target=\"_blank\" rel=\"noopener\" title=\"\">no need for component libraries<\/a>!):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"471\" height=\"275\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-2.png\" alt=\"\" class=\"wp-image-2087\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-2.png 471w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-2-300x175.png 300w\" sizes=\"auto, (max-width: 471px) 100vw, 471px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>We use <code>ngModel<\/code> (which is from <code>FormsModule<\/code>) to capture the current value selected by the user and set a default value for those dates if needed. To do so, let&#8217;s use two signals created by the <code>model()<\/code> function from <code>@angular\/core<\/code>:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"392\" height=\"153\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-3.png\" alt=\"\" class=\"wp-image-2088\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-3.png 392w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-3-300x117.png 300w\" sizes=\"auto, (max-width: 392px) 100vw, 392px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Two important things to note:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>These two variables are signals and work seamlessly with <code>ngModel<\/code><\/li>\n\n\n\n<li>These variables enable two-way data bindings with the parent component as follows:<\/li>\n<\/ol>\n\n\n\n<p class=\"has-text-align-center\"><img decoding=\"async\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlgAAAAaCAYAAABraSKSAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAACKGSURBVHhe7Z0LXJVF3vi\/IXI9gIDcOcDhcJGLioioeClcTUvTvGy21rrmR22rdcvd\/rpba1v5tmUfd7PXrC1738paXXe1TctSwygVUVFCFLkIiiB34cj9ItB\/nnMe4IAHPRhY++7z\/Xzmw\/PMDM\/MMzO\/md\/8ZuY5d7h5+n2HgoKCgoKCgoJCv2Eh\/1VQUFBQUFBQUOgnFAVLQUFBQUFBQaGfURQsBQUFBQUFBYV+RlGwFBQUFBQUFBT6GWWTu4KCxKN7+eOCIPlG5vwOXnj8OfnGmAi8lzzN+IlqHK6eYvfTa9DJIQr9i3ZtApP8m6nKTOTw2xvQ1ckBxsS\/x8pn4nCRb\/VUHuWtBx+hXL5VGCD6WPaWU19kysw4vB1qOPv2PE6myAEKMGY98x8djUNtISl7N5CRkCEHdCfqzWzmBMs3Mlk7Q9nxtnyjcGOsA5gwJQS7wlN8ebZS9hwY+teC5bOO6P\/aR\/SseNlD4d8DP5wWbGf8k6\/gZCN79YnlhIh6j1+yXL7\/N8TKGhtba65dLeTSJdmVmBgiIp5l\/sd7WbksnphgNf6+7gyWgxT6HwcvUcaBEYyf+ytW\/+swd89UyyFG1JVT3FFnl8ppHCTq0sEaSzlYYQARcmMr5MaysbxLbi6Xc00O7iKe0NdSWPf8YuLHBOHv74aLSg4aaKZvY\/WRfFav\/5H3Typ3vP3VaMfE8\/Dze1n95os4yEHG1JZ0tHXhrqLvtxys5MB\/N7wi2PX7Reya5ih7DDzOUdFE+bvSqhtY5UriR7REeB8eD28mJP4++V7h9jEdjxHO2LhF4TFM9voPpfzQVN5fJrt1b8i+HcQzae1yYtybKdj7HGvvDOWFW7SSOD\/+MUve\/ZiYMbLHQDP3ryK9BOLnyvc98F6fzstiEOp0X6Wz8s3X8XaXI\/SVm6RnLmmPizKeMolX305FZ6sm\/rd\/JaLnwJyyhl0ddbZsK1mNsv8t4ci6xxex\/\/eTWCHu5s+cJ65nsc7LENpXokaMZPOCkaxwkj0GGHPSi582S7zTIjZHiRvNKD7thwGuNnNrl9yYsOg6rH6RJWPcaLq0j03zAnhh2iQOJMqBt531LDNu68L9cU8Cd\/98jhzeV+YQsyGBJRvW4yz73BKJj7BpWihr5z3HgUvNOI9YzLLnF8qBXeSt62jrwh0qlH1vkahJ+ragr38bLR+I6\/0PmpjE3Fb6Vwa7YRHAuPAhUHqGo0Wy3wDSNwXL2h1fj4FSlT1xGqbFx99Tvle4fWzhws4Uik5+Sn667KVwPT9\/mim+YjBJ3cJbL2+lVfa+FWz9gwgdFoR3t7WVAcTXkJ5W5L93KkjbuZs9OxM5WSKUrhFzWPn3BGIi5OC+YFZ65lKI7sN5vLWzkFarCO5ec\/2g03\/UUFglXwqqWlrkq1vD2UNNULAatZ3sMcCYk15iRbV8JWhq4fu9oTk8y70zxKBdl8pHj\/6S4h\/Jum3ThUTR1ndzICmXGtsg4h99\/RatXO54h4n2HqbGVvb5XpRvJfHRDSSLanKfvJiogbT0lVXRueou2oKpFfjbT\/\/KoDHWkZEEWrdx4exZmvU+Vnj6uGM9QKYmsx5r7RHC5Fk\/5Ze\/mEV8sCmjpcK\/O63pa8n5ZDMt7bKHwnVETIzARighJ3dskH3+r1FN3sYnSd74CLseGsGfduTSZBXEnF+\/KIf\/sNRu3E1aoxh0hs34fpYChdvLkjgixby8PGUHeT+OEVxPY8lR0dafJHHNVF6b+xLJYlB3nrCCuyfIEX5I6rZw4JtCMf5HELlA9lP4ngwhKtxddCQ5nMyVvXAg5K5ZLFv2U+ZMDMHTWvbuJ3rfpmAhNLuQ0YwdFYKv0yBob6OmIocz52vlCCqsYtcTPkOLsxCe9roCsr4qk8OMkPZlPTYGvcW6vYWmylLy979GSVamPrhbuETQfOL\/a758A0WfzCDnpHxDGKpZq4iI8cNOyrl4ni5nP+e29U0xsJm1k\/HjDNOCkj2rKPB8jtExzlgKdbMhaxenPtpisE7EbCb+fq0+XntrCw0VeVzYuZbKMqNeQh\/HQygnKThNjcdDPLa9VUfR52+QeyJJjtSjrER44ccnsHxgOqpj60n9rMNW3j0e4p0aClPI2L6Wuj51TPH4\/HYNIZWfklw4kpF3ivIS79ZamSfKak1X\/o3ez0AeaX944voN2xZRqO59nLBoP1Qd+SrLJLdnWfTA6cE9REfWk7PpZxR1NA2PJwh6cDo+blZ67b5VtJsLn7xGkdwezK6b285i\/CUTdfV5sjqq1RSTX2fhyniGuTtiI8Smg7yd83h3Yyox7+Uz32iD6vi1+cLJN9VH2TRzEcX6m+XM3vss42XBaG2s4dKxHexY+xIdEigt662cYFjaydv5CIm+r7JknJteqGuzdrBp2RocjOJIaBfm83KnASiXXROn0ilePajdtIlk8T7xwaORjFj6LbcrE8T\/y4cB2pqpLc8lcdMvSZaXKozzJHHD9CKeZfYzCxnj72joiFpqyN6zgfc3btUHX88GLl3+lX7vm9Rqe8u3KR57+3MeMG7q3ajn+Pqf8rsv5VsJMWvuKGdThAWH8Zv4MDydbbDqnKbWcWLrHtYWwYoHFzFfI3sLYpcsYr98TfVpXnkzA73US3tQlowUki8Q\/VmLroyUxOO8eL5r1i4t6f0uxlCmBft3ss\/tLlZEDRVy2Ubd+aP8YWchk8xNr5MWrjXJlwOMe4ha1G8NeaL99k48oetfZP44NQ6S3Ii2VX5+H3976knKO7orSXbcj7LrmJq7pxritVbl8vmGRzrbH6hxf+o9HpodhLvUV9UVkrjPjGU0odDs+fh+xiyLIGLaHA4k7RaeN5NBaalxob4tGohj5ZF8+Rp0SS\/x6pot8l2PfAlqL4l3+dMisk3vZafpdCG62Wq8wySrWsdzzGDaC3y6ZoyhTZki72PiH31XvjFQ13wjK5EV86fFsSjKG1XHuJt3kk0f55PUMe5KS433OHHiixw8J4\/Cz16qnBpyD37NmtS6TsvYhOixrIwPEOObCK8vJvHIDY4H3UQG+0xQNKOk1cGjp8Q0uYNacjJycAvT4hs5Ue8aSnM4nnyCc2Xf33I2yF7l9Lx8LeNA4MSfMEuo8aMC3bBvLiPjZDIHEg6TklFAaX2bIVrgi8Q8GI6quZS8rxMpKnclYHwIVtaDaLucREmO3NCuWdFUc4XynBx0tSoG+\/jhN2oibYWfU1MlXqAzvBGrEE9sy9JI\/zqFMhFfclfzUmjR76lQYTfvv4kd40Zzfgq5SalUNnuJghmJr7ctRempmHscsr3RlprSNn16Vtf8cQxooeirFK7a++EROBzLqo8QeiA021JbWSzykU9Niy0OgUGoY8dRn\/IpDR1l7z0TzTBPHPyG0HDmEBcz6xjko8ErcgTNZ3ZR1yDi9CyrYhU+cWHY2VrRblRWlpPeIW6mn0g\/k\/OJxyjX2eIYHo5\/uIayY4f6oFhocIybiKurBtehdVxOOkSZzgmnQD98ooajO7KfZqmwOt8vh3qnUJxVOkq\/+pzu\/W4Yzr\/4E6NHuNByUZT70VQqpHyFirIYEcKVwwmiqx6N65RwHEW+89NS5f+LZ+j0O3H9LpvcfQmGTa+qVYSvuhdvyxoKkhIoOF8DnuEEjBnLtZxd1AppMrtu+puxi5ka6YIuYyOpJ2S\/bsQS9vBk1LUZfL7zM9N1oXqRh99eyAiHZopTj\/JNcjrZ57KFyycvcwtCP6fRRkNlYTbF4q\/GuY28xL0cOSXFES7jBBdPpcrPtqHRwZKS88K\/uAErZy+0kbFEDbfk8P6j+hjXrL2oKWvDOdwL1XfBaLStQlk\/QaWzGo1mJO42G0lJl+Lkk93kSqiXPeWpuzmYJKd3LpXzx47q69th2mOM9asn83+3ygqeRDbXxi4VCpAT9UVvkS3yj4U7DTUl+neqarfHRRNE1JRptKS8R4HotQx5unl6qJ5m\/v+INN2buZiUyJEThTR6aIgcI8rYJpW0lF4GxbilIp\/2VF58i\/NdY5kRowl9SDyDQk5sE21K9h1k7URdUQ5ZWabcWb49dprzVw1xR0cOJ3xwIftSxAtpQ5joXceZxHyOdVS6axhv\/HwUnndc5WL6GY6IfjH7QqFwxeSW1pDZLNJrrKWuuJArFm74ObdSIDrsb7KkOMLllXGsvBn9Ql1rM3Z1V7go\/IvrBuHqpSZkuB\/Di7NJkPPT3iyGp\/IW3LWuqFqt0fg1k3LkPNV2Hvj5BxJ09Qz7L5mZnoSnPz8PtuTi8RyhdLmzMMqTuuxv+eTyLRwoFxPiCXeqofAwSQkdst8dp7ultlXNmS2ijZgcT4XC\/N\/\/YOlY0cfkC7k5mEpBuztBEdGMifHi+J4EvUx43\/8U4d7uBDrWk37oazKr7VEHaYgYruHMjt1CTRbMfZ8nhZLk0lLIyQNfc7LUhbGThmFrY0lrZx6nEb00Etueec4di\/bhYajbaji4O0F43EwGXal3bKDgXAmWGg0urWKysfswZ\/RtXbhvEyk9b2jHDqv3snquhkGVGRz+IpnzOku8wkcyfmIsmdu72mk38kSfI\/Lp3VDCQVEGJjHVb7VbY9d+hQsm27pwp1M5nilLuYOh\/qsyvuXzUidmTvJHJfqn7eelgcvA\/JkzWTHKlZbC03yVcoHCFpUQi1AmelaSdK7W0K70bcodN19b6s6d4ZucWpy8fPEb5o5vZi7fSGO4\/yg2zg3BqaWCtKR0TlRaM3G0v9AZLGkrzuEfFwyLdhI3lcE+Y0XU5Mn4W+eTfCCXys6mLiYppQVknj1N6vkK2myH4OErZDB8BLHhPqjqSsjX3bqiZcKC5cXwSC8c2yo5uesLjleYfrhTbDh2Qi\/N+WAJRfJmscqy15j0QJi8tinTtB\/dsc65FCX7xCD7h+kExNxHYe52o\/DluM6Kwrk2j8pjJrR1i5\/hG6WiNXcXp97fIhlR4NhmdE07GR8TpbeA6Xpaw3oi\/jdR+t\/CD8QgZ0jPJ8SKtFefEM8R4UUueD4qNH\/feEgT873KXVR2HDQ4JoJTX2H8kii8xkZRcTBNDjBQn\/IXsr40nDmubHyH+Nl+OPiL9xXt40Zl1XXaJh6PWE8sdCmcen1tp5JTVi49KxxXD5F+mWyZ6nV9pIcFyqqUCxtWUCE\/TFe\/XXSGWtzCxaT2rPAwer\/2YfeBSOM6An9BSJAVDalbSPl4l+wp8pUyHRvd\/h7KWBeWMQsIEPlsOJlEh6ja3DUBDwtRDu\/9rKscDj8BL96HR+QE4Zdkft3cdoJwkRpWeXWv78yEILzF7LQp4xO2rHrOpBKm2\/EkyeKvZOmJDxSPOyLuu8TDiKMUvC2cfJcsZseT\/r6Ne0fGE8EGvTWpae9zwn89EQui0QZb89WyqZy8IALObyP093G4+y+n6U0pjmBlArOj3ag9L9LbJHmYR6s8n+rk2AaShSx0sGfhx\/xxZTQxP53D4Yzdcp4EN0vvkRnEiCl23o5f8u4mg8KYvHE5jZLFIFrabGzw6w1L2QpgLsd3vclx+fpmvCPK+R35mi8\/I9HYsiWhHqpfoixNPcSaQ00m962cyMtHGu\/inSOZoBFxs\/PZXGII60ZTDe+fFBMNPUJjTNTywaqxhEcJYbxoMPsWFBWzuWgQ4dNCCAq0Yv\/mw7wjNcISFbsWR+Dp5ciJL81MTyLtMNM7u68M5r\/ciwmln3B3laxv5TRKbdMUql8RH21N6\/kd\/OWRNZ3ylbUhncfGjUY6d9PV29aQ\/OdJHNBbkdU0bT3M7EA1fuJO2toVMSMaBynOhknskeUqedle1i0xYyNhXU\/JvpkM7iB7o2SVW47btHi0IgdnNz5pNEHpYDnxkhJafZQt8zos1KKqnzrMywsiiRJdWvGNujQjS7hZ5O\/nf3qez+mNEuP6L+SJl7fJ1zIWaqZEqsTk+jCr\/l5oKIuT+cxoms2qqABmiLfplBVBveibl39tKMcPmkX7nK7GQ9ozL8aZn0VrUYm6ObHjIGv1bTOfD8rHsn3O9ablm8pgX3EbzXBP0f9+m0pOL6tdbdWXOZkgnLUrMXffw1gfd8LDvEjMu3U7Wqdxu4tCjh\/PQ3dNJDL\/YZ5YPIdpYwOuW5u0sBE9nJgl1BnvxK+sM8wijLGKx3nWa4Q\/uYfxzwj36wn6zsnSplcDpmm8\/FCJ3FqKGdOd0icBZDc+Vjyn4y0qj3Dxs09J780d7a4U6bl8zjCASxSuJeUPM7qW7JzFwH\/\/O4xYLed9QbheI7W0vV7DaRCKUSft3Q8pm1dWQdhLj3Uew3ij95MUNaQPAehVYaF8HjTxXp3uq+7PrC6j1qjPaMnKFYOBFY4+5m8ysNR4CuWwhcqcLuVKT5lQrnrq3g5aXMetwufh7YyZrcWqKY+cfZ\/KgWA7VKpzFSGPGb2fUK70h0MGmxgxb1Q3t51cqqSpmsq99\/0\/+xNJKWnGJmIx677J5pl\/JjD\/+Rfx87+VUzkReD++jYV\/S+ePX2YL91cmSSf6pGPxhgjduZxhUK4k9i7iTxMDjJYn+pHop4l\/LYGVe6U8CfdIhL5pDrbt23FDb19DfO3CbUanueTlmBsMKJb6sGaajDbB3naycsgUfa7nhHns+n\/z+PviGNbFDCW2j0qfHisVK6bFsGXFPD59SrhlI\/XflLKy7uVhJYVs65CJotNicNzG\/C87FLQfJ+WVUv6ccOntxOwEtf6dLYMX8sfOtpAvlCvDsmh3K0A1VZ1L9IVc6zEBsJWKTfS1ecaTlsLqW1xq6qMM9koQ7lK7djIsIXa29wWGfqHXyYLK8M2c1pYfsH49HPEU46uVZhJbpBOGslsVLY271wtq5dWuAaeuhyLjILXplgrOGSn+dbo6MboMPCHRITi2l3MuTTYLm6Brr\/kcoVxZ6RWu4yfNWF6+ASYUrEZKv\/2Gbe9\/wIefnyKnyYGQUVOY\/8hSHllwN2N9jVpDa7OJ750YYTEf9VNriIoNw6apkMoC4Yrr+rDUdT2V36zn8J9\/18P9xWC10VvDNlPZm8sx8VW79l6qV\/UE4auEixaiXy7nvfw69dF8blZWMi3ndpl4v7WU6BtlAU1pJt6r0+3q98ZqKB4rLEzYOq\/DI4oRs6YTEuKs35dSnb6nS0HqoCmTtOve73ekJ\/Shbn4QymmSTHFDxEBh8DDBFhJ\/OpUXnnmDPcdy0VmriZq6mMf+lsCSx+PkOOagRvvadlYuiiPSoVr+5k05tTcqjraeBd0fxKH1N1gfiqVBLeJ1HnvtV9wdLQaGSvk7POXd7NV9pILEdU\/y6qoebn1ve7DU+LhL+ammvI8fqJT2YCUm9Ob+ySvT5Ijm0FTGU2\/s4IkPD5J4toJmxwBip93NulX38FxfjpJbDGX9itnMFzN7h6ZSCi4LV3qTAae9zaTF7MdMY6PURhxxCDTc90Zx4kvXt4VVLxlZr8ykTSjg8mWfWBiMj\/ijK5d2QN+CDN6EpowdJt5vtWyNM8Gdbkj6XK2QtT4h7cEy2c5l9\/YyOaL5lCZ\/xpo3P+7hjvNPOdxs2m7HqdUeWEcy3H8QzRfPknZdd2WF75i7eWDxUpbNnchwbzvqC0\/x2fYP+Ov2A5ws1e9PumVMKFgdtFFTcJov\/\/GRPqHjuVcZ5OJLSIDhFGG7ZL6w88fJTX9rwFWFvXypxysKN9Eflny2gNS3nyDnI+E+OX29lcsYa5XpTBWdo0Yk6Rw5BcvqNFp1xk7aHNLPDAvXL2flbllA+vty3o9euiXl0KyyIkUyOGEVGIXDtZ7vl0l7L2bNG+LkgYPRh0OthgXpNz7Wld1ol3Z32otK9Ut8HtFPmFpP7o60BPuHGSQ+\/xoXhMbrFLMEH6nHkqktLEX61oqbtrnH+wnX9GMfNnaTVyKk0zaIiOmyl0kKaTq0geQ1M3lrdihrf72PYqwJHWPqGzvWDB4iX3ZjBhEhQnAu7Gbt7EnyN29e4mzvky+zGWxrvqJnOfdpxkufWbiUwVmpeqZE4DeohuRXQ9m0WP4Oz77CG8pEb+kVZ0r\/50bUFHd0Kbu7u6xelqxUyw2ffZA+tGjwMZvUA5\/xySe9uU85dF6OaDZt5F4u45UvDvOLN3Yyf1cOLRbOjIw0WF26Y4WVqQ\/4engQJLrTgi938ODWozyxU7gv8vpBgeolvR8InajrJtHWtdG9fAJhfwbFoov0HhmPQ2aPtpCS2Kc+t1EavW2FcmRspFc7mfxgZzdUcxg\/MxobmsnTb1G5BRkUhW7asnWUAjFBtgkejbah5\/vto7euz31csD7fxTm9TTh64fxRE23cyB04LUc0g5IrFIoy9RymxrO2ibRqY9fSp1+wqJU20tt6EuEqewhUzirRWgcW33HD8bS4ypkUU5s2HQgM8cXNupZLxw\/w4Xsf8OEXp7lU3XNvxK1hYpP79XzXXEPxhUxS03Mpr2mgrrGN5qaReERp8BgxlXYLHwaHLCEy1ptme1FcHRu3LWNxi9Mw1Gs0LW0arMMWETwvgEFXVdg6u\/Cd7SAaxXMNr3IFC+19uPsFMdQvlDabcGx8p+DoXk99ibSr+SwNNjPxHaYVGudUMTBpuMNlNHZh8xk65Ao1+jjm4IdN1MM4BQQwVNpUf62FWotQ7OyEcFYarZ67TEMd6YOjVyQtlqGoopYTfpc7zY22qIZ40SZmkvVFeXyn3+TuQm3WR3T+ew8\/k2U1KUCMr8YHAkpF5zAe7xFavMbNxH5IEO1DorDTzsYrUIUuP8fwbLOQN7kLcbeLjucOKz\/shi8nNM4Tq2bp9J+0yb2jHGKx843FQSNtcr+DhgZPLMV9Z3noimjwm4K3NhyfkZNps\/bDykuEdyv3Hpvcv8ujpiISj1EaUZ8+lJxI0tdxe4kbVrHD8QmfgUtIpBh9Q7H2nYhL3J20ZSRxzdy6GQhuusldFIXNFMbGBeCv1nDyX\/uun4lJP3Xx4uOoA+NE53gP6njxzJ\/FobG3pDz9Q44ldikOtQ7TxLPUaEY8xFBtJI5R9xA89x4GJewTnZYaf3Gt8fNG7TcM26iFTFj9GMGDdNjbuzNk+Giqqyuwn\/k04ZM0aMO9sBczwwavONT+TlzOMKGgXBlNyNxh+AVNQxM2UkzqRPuesRDP+t0Ui6I1bHK3pMVR5GXc\/UQ\/\/icWzQzAviWXXc8s0m9gJ3whd0Wr8QiajIWPeC+hgD1wryuNDfYMcfXGwcOaS8fkTfo3SY80e2zvn0xo6GTG3jML56DRuMTcI5JYgXPVDkOcHrg\/8yqzg+0pSHiWw8m9zepNb3Ivykzh+IneXNcGd7PwD2HzXZ6EOtgz2nsIsSEalowNxsWmlbyUb9knlZVMfps9c4d74af1IsamDe3QIUyMGIL7hatkD3Jm5hhvfDwc8G0fxMiQIH470wfLGjtsnewZbltNTX4zwyP9me7nzjCtkOjWZpwsrIi1bSJFd73qccP05Dj9ihmb3MlwY+gDcWj9NDScfI\/LRuVj4DBXQpcyVkwAx9z\/EGrRvm317WUFY8ObyEwx5Fy\/yd21qttBjJ5+FfaiPY0NInTifIb4RjFk6tMsmuhNi721UR4Nm9xdWtto8Z8i0lnJ3N8sJsZDyHjSet7dJMUxRwZ3U3lZyoVo82MeI9pfTfisaVh7jRXyL2RoQgDZyVJnkk2R2yzGRQUx4t6lhIyMZXCYSFf0DxPivcg4ZKLDUT3L3DWTcG9MZc\/TO3pXZEz1W1fz+NZkO5ddxwZ3s6in2caXicEBjB\/lxXihc2pcnPRtfrbjVRLL5Dao3+TuRFXuGT7vGIp7+OU3WzMzUk1QuDvD7\/iO0KBQfjPKjTY7UTc9Nrn3GxZaJvwkCOeKdD5PK5d1DWPaqCnPJunQt2SX1tB8K4aMG2CWgtVJe4teudJTdYyKutE4hvjhExKKm3cLl7YnQUwoVh1KQ9Npqu8Yx9AgDV7DRBxfS2q+\/ogSu\/F4eKpwDhhCVeeptWoachq5pg7FNUCDZ2goHqISndsqKDhr0Lhb8\/ZTVOqDtVDCvES4p0jXI8ATu+YiLp+Tdm2bQzQeDy0lfKQYwKVbladIRzzHXmd0Ak5QXkD1UCEoWkNeXIc0UrT3E+o0o3FzccHV3ZKSZDG7MkPBMllWCTnYhPp0KaOC70o\/pzDTiUH+WjyCQ\/Xv6KH1QWVdT+lJg5JiHrKC1ZZKVpqKgPhYvMUszqIqj7MfPIOuTlINOspBKmdJuZL+zxZnqSy6lccVmtIzuWIRgkrjh3dHufsJZa3hIsX6zyuYOEUo3rnO\/X68A4OwvyObsouiIFpTqTxWRK1LEG7CX2oTHmJQcXa1pTbjE+obzKybgcAMBYusQmrjZjEiOILIKHvOHT7cfR9azFJmzIolMnIYoeHChagZYtHAxSNb2b7+re5xs46S7TgZrYijDTXE1\/q4Un1pC3n52eQ1jCRklPAbJoWJyUlZAv88Zs8Y0Tk5+Ghw0GXhMHM5U6OFciU9z97LkKZLlXwCqge6fWQ3xeIvZqKaYDl\/gRq+q9hI+qkOBcsFT8k\/PAi1fTOlGYnseOW3ZKTLe0DSStDFTCFSE0CweEetSxsZ\/\/yEK2Gj8RcTJrWPJWc6lJqbpCcNSuc\/vUipTzD+oUEMCzPE0Xi60FL0Bhnd1oUi8P7tdpbOVGNddZRtz2xETJ57wbSC1Z94isnIz8eJ\/AapCdUKp3YRkwEdOYcSeeF0S\/flqepSihrsGBHghVrjr48f5GlLfU4eR6oqabJwZXiAeEawcF6DqTiaxAnbEELd7fBUW6E7UkXkgp8wJVyaLgnsXQ1p2l3ho7Mm9ubcKL2ug2H9hzkKFie46CgpGBoiJkymNPsoFSXd81578DNSr4m+VihZwbI8hAZ64XKtgm++MOy7NEfBIkOWqzANwVKb8m3j5ObDWEonCXsoWO7OGjkddwbX5ZLyr41sffk9wwEqoRTdXAa7+gpdUg0NMaPR+qr1sqGXIdfmztONrSlbSSrQ4CLyJcl7mJSukP2hNjVk7Pys+6pO9LPM3rCY6CFt5P3rOQ6eMGV5kTGn3\/qe5Ofncra8VZSlkOUgQ5uS2rxbSynbc+Scm6FgtVyV22agNxqteI5HuyhzMX6MVKMaIAXLbuQEpvhbcO7rr8g1uZWtjab6FrO\/QNBXlB97\/qFQr2PMo2No6\/YdrP5CPm1ICsl\/7jqRqHADOr7v1NJMU4cma+rHnlWLmfTms9wbaDj10Xo5kU3KjwoPGNIP284fIf+uYHUGO1bPJK2nga7HDw5bSr+N1+2bYgoDhvQ7f2vjxERYyE2H0mvyx57VuK\/exmOz1ehXL1sKSVz3Q\/5czo8QqR2vjdefRJYOchQnbGDT89cfVOn2Y8\/S726K+Hk7Ani3D6eD\/zPwIn7xPYS3nGbb30\/1aTmzv+ibBUuhn3BGNWMpGg+oOPIyVf0+OncsERZzWbKyyb4KN8AnDjEpo1JXQ3W17C6fIq2n+V4Ia8G\/dpNUZklNcxsWTYWcO5CgKLEDhH30\/ViWnSBp9xa2P\/MMxdctLwncRN0F2dMo15vuShWVl7M4q9TLwOMSi2eADbVVRnJTnmtCJmqoT3qPbw7WU\/pdGy2D2yhNNr0U\/B+L1I61LWR\/\/SX7XnqKL3eb1j4lmXAS5akva51o66K9Xzy1lfwsOYKCAWs7rFoquZCRRVHH9ztvM4oF63bgvBz1zCiDid\/SHic\/T\/0X0dsrkzj+2roBGAQUC5aCgoKCgsIPyQ1OESr0G1aeuEk\/ZC25QBcsW3WUHNtO8usDoVwpKCgoKCgo\/NAoFiwFBQUFBQUFhX5GsWApKCgoKCgoKPQzioKloKCgoKCgoNDPKAqWgoKCgoKCgkK\/Av8feTKH8uQOO1gAAAAASUVORK5CYII=\" alt=\"\"><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><code>start<\/code> and <code>end<\/code> are signals as well. We can use those signals to pass a default value to the child component or keep that value empty if we don&#8217;t want any:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"584\" height=\"158\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-4.png\" alt=\"\" class=\"wp-image-2090\" style=\"width:584px;height:auto\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-4.png 584w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-4-300x81.png 300w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>And that code is 100% functional as-is. No need for <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/reactive-or-template-driven-forms\/\" target=\"_blank\" rel=\"noopener\" title=\"\">template-driven forms or reactive forms<\/a>! Now, let&#8217;s add some features to our date-range picker component. Let&#8217;s say we want to enforce the rule that the start date cannot be after the end date and vice versa. The following bindings do the trick using the <code>min<\/code> and <code>max<\/code> HTML attributes:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"637\" height=\"74\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-5.png\" alt=\"\" class=\"wp-image-2091\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-5.png 637w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-5-300x35.png 300w\" sizes=\"auto, (max-width: 637px) 100vw, 637px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Because this is all based on signals, it&#8217;s all reactive by default. Changing the start date or the end date automatically updates the range of what&#8217;s selectable in the other date input:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"588\" height=\"390\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/date-range.gif\" alt=\"\" class=\"wp-image-2092\"\/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Adding more features is now as easy as adding more signals and bindings. For instance, I want to enforce a minimum start date. I added a new signal input called <code>minDate<\/code> and I bind it to the <code>min<\/code> attribute of our <code>startDate<\/code>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"764\" height=\"275\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-6.png\" alt=\"\" class=\"wp-image-2093\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-6.png 764w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-6-300x108.png 300w\" sizes=\"auto, (max-width: 764px) 100vw, 764px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>And then, in the parent component, we can pass a minimum start date:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"574\" height=\"63\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-7.png\" alt=\"\" class=\"wp-image-2094\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-7.png 574w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/06\/image-7-300x33.png 300w\" sizes=\"auto, (max-width: 574px) 100vw, 574px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>You can find that <a href=\"https:\/\/stackblitz.com\/edit\/at-date-range-picker?file=src%2Fdate-range-picker.component.ts,src%2Fmain.ts\" target=\"_blank\" rel=\"noopener\" title=\"\">code example in action on Stackblitz here<\/a>. Note that our date range picker has less than 20 lines of code and relies on basic HTML features (<code>input<\/code>, <code>min<\/code>, <code>max<\/code>) instead of <a href=\"https:\/\/blog.angulartraining.com\/how-to-pick-the-right-dependencies-for-your-angular-application-328ce637b982\" target=\"_blank\" rel=\"noopener\" title=\"\">adding dependencies that would impact performance<\/a>.<\/p>\n\n\n\n<p>Please email me if you&#8217;d like me to add more features to that example in a future post. I&#8217;m always happy to cover what really matters to most people reading these posts.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In today&#8217;s post, I want to showcase several Angular framework features in one example. More specifically, we&#8217;ll use standalone components, signals with model() and input(), as well as forms. Our goal is to build a reusable date-range picker component to select two dates: To do so, let&#8217;s create a standalone component with two HTML date [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,21,22,29],"tags":[],"class_list":["post-2085","post","type-post","status-publish","format-standard","hentry","category-angular","category-architecture","category-forms","category-signals"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2085","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/comments?post=2085"}],"version-history":[{"count":3,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2085\/revisions"}],"predecessor-version":[{"id":2096,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2085\/revisions\/2096"}],"wp:attachment":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/media?parent=2085"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/categories?post=2085"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/tags?post=2085"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}