The Pragmatic StudioTop developer training from the folks who wrote the booksThe Pragmatic Studiohttps://pragmaticstudio.com/blog2024-03-24T00:00:00ZUpcoming Phoenix and Ecto CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2024/03/24/upcoming-phoenix-ecto-course2024-03-24T00:00:00Z2024-03-24T00:00:00Z<figure>
<img src="/images/blog/2024/03/cat-out-of-bag.jpg" width="500" />
</figure>
<p>It’s time to let the cat out of the bag!</p>
<p>By popular demand, our next course is on <strong>Phoenix and Ecto</strong>.</p>
<p>Dare we say, this is one <strong>cool</strong> cat. 😸</p>
<p>Taking a step-by-step approach, we’ll build a full-featured application that showcases the power and elegance of this <em>amazing</em> stack.</p>
<p>And by the end, you’ll be saying “<strong>Aha, now I get how to put everything together!</strong>” 🤩</p>
<p>Right now the course stands at around 50 modules. (Yeah, it’s super comprehensive!)</p>
<p>We start from scratch, and build out features incrementally. Topics include:</p>
<ul>
<li>Routing</li>
<li>Controllers</li>
<li>HEEx Templates</li>
<li>Components</li>
<li>Page Navigation</li>
<li>Ecto Schemas and Migrations</li>
<li>Ecto Queries</li>
<li>Designing Context Modules</li>
<li>Ecto Changesets</li>
<li>Building Forms</li>
<li>Phoenix and Ecto Generators</li>
<li>Full Admin UI From Scratch</li>
<li>One-to-Many Associations</li>
<li>Streams</li>
<li>Preloading Associations</li>
<li>User Accounts</li>
<li>Plugs and Pipelines</li>
<li>Authentication</li>
<li>Authorization</li>
<li>Live Sessions</li>
<li>Many-to-Many Associations</li>
<li>Phoenix PubSub</li>
<li>Presence Tracking</li>
<li>Uploading Images</li>
</ul>
<p>So… when is it coming?</p>
<p>At this point we don’t have an ETA. We’re waiting for the next milestone versions of Phoenix and LiveView before hitting “record” on 50+ videos. 😳</p>
<p>In the meantime, we have some <strong>Phoenix, Ecto, and LiveView technical goodies we’d love to share with you</strong>. If you’re interested, <a href="https://pragmaticstudio.com/phoenix">sign up to get the newsletter</a> exclusively for this upcoming course.</p>
<p>We’re really pleased with how the course came together, and very much look forward to rolling it out to you! We think you’re gonna 🧡 it.</p>
Ruby Course Update and What's NextThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/09/27/ruby-course-update2023-09-27T00:00:00Z2023-09-27T00:00:00Z<figure>
<img src="/images/blog/2023/09/torch-rocket.jpg" width="500" />
</figure>
<p>Why was the astronaut quiet?</p>
<p>Because he <em>spaced</em> out.</p>
<p>😂</p>
<p>You’d be forgiven for thinking we spent our summer staring vacantly into the galaxies. It’s certainly been awhile since our last newsletter.</p>
<p>And while we did indeed gaze at the night sky a few times, we’ve mostly been in the Studio updating our first-ever video course: Ruby Programming.</p>
<p>The Ruby language is friendly, productive, and stable—just three of the reasons we still love it. But after ten years, the course was getting a little far out there, if you know what we mean. 🪐</p>
<p><strong>So today we’re excited to announce that our long-time popular <a href="https://pragmaticstudio.com/courses/ruby">Ruby Programming</a> course has been entirely updated for Ruby 3.2!</strong></p>
<p>In addition to re-filming all the live-coding videos, we added new sections on unit testing, immutable data values, and exception handling. And we streamlined it so you can get through all 32 videos in just 4 hours. More time for star-gazing! ✨</p>
<p>We also updated all the exercises, and added a new “Ruby in Rails” section to each one. These new sections have examples of Ruby concepts being applied in the context of a Rails application. Even if you’re not using Rails, it’s a great way to see Ruby code used in the wild.</p>
<p>We think you’re gonna love it!</p>
<h3 id="new-to-ruby-or-just-need-a-refresher">New to Ruby, or just need a refresher?</h3>
<p>We distilled everything you need to know about Ruby, assembled it in the right order, and neatly packaged it as a <a href="https://pragmaticstudio.com/courses/ruby">video course</a> that’s paced for newcomers. 🤩</p>
<figure>
<a href="https://pragmaticstudio.com/courses/ruby">
<img src="/images/courses/ruby-2ed-large.png" width="400" />
</a>
</figure>
<p>Access to the course includes:</p>
<ul>
<li>
<p><strong>32 carefully-crafted videos</strong> where we build a Ruby gem from scratch</p>
</li>
<li>
<p><strong>26-chapter workbook with exercises</strong> where you build a <em>different</em> Ruby gem than in the videos</p>
</li>
<li>
<p><strong>Animations</strong> to visualize the key concepts and get a solid mental model for OO programming</p>
</li>
<li>
<p><strong>Source code</strong> for each video and exercise, and the final code for <strong>two Ruby gems</strong></p>
</li>
<li>
<p><strong>No time limit or subscription</strong>: with a one-time payment you own the course forever!</p>
</li>
</ul>
<h3 id="its-a-free-update-if-you-own-the-previous-version-of-the-course">It’s a free update if you own the previous version of the course!</h3>
<p>Yup, if you already own the original Ruby course (thank you!), then the updated course is free. 🙌</p>
<p>Just head over to your <a href="https://pragmaticstudio.com/my_account">account dashboard</a> and under “Free Updates” click the big green “REDEEM” button. You’ll still have access to your original Ruby course, plus you’ll get the updated course.</p>
<h3 id="do-you-need-to-retake-the-updated-course">Do you need to retake the updated course?</h3>
<p>Well, it depends.</p>
<p>If you completed the previous version of the course in the past, say, six months, then you might want to dip back into the new modules on unit testing, struct and data values, and exception handling. It also might be worth peeking at the new “Ruby in Rails” sections of the exercises.</p>
<p>For the rest of you, the fundamentals of Ruby haven’t changed much over the years. And you’ve likely traveled far beyond the fundamentals by now.</p>
<p>All the same, we hope you’ll appreciate having an updated course to refer back to as you continue your journey with Ruby and Rails. 🧑🚀 🚀</p>
<h3 id="whats-next-">What’s Next? 👀</h3>
<p>So far this year we’ve been focused on course updates (<a href="https://pragmaticstudio.com/courses/ruby">Ruby</a> and <a href="https://pragmaticstudio.com/courses/phoenix-liveview">LiveView</a>), but now we have our sights set on a brand new course. The example application is nearly complete and the outline has moved from the back of a napkin to an actual Markdown file.</p>
<p>If plans stay on track, something extraordinary will soon take flight. In fact, some might even say this hot new course will have wings. 😉</p>
<p>Keep your eyes on the horizon…</p>
Updated Phoenix LiveView Course Officially Launches!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/04/06/liveview-2ed-course-update-72023-04-06T00:00:00Z2023-04-06T00:00:00Z<p>Today we’re excited to announce that our updated <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">Phoenix LiveView</a> course is now content-complete and out of early access! 🥳</p>
<p>We just released the final batch of 4 new videos which are all about file uploads. That brings the total course to <strong>35 carefully-crafted videos (nearly 6 hours) and 50+ guided exercises</strong> to lock in what you learn.</p>
<p>It’s up-to-date with the very latest versions of Phoenix and LiveView. Indeed, this course is as hot and fresh as it gets! 🔥</p>
<p>Now onto what’s new this week…</p>
<h3 id="file-uploads-ui">File Uploads UI</h3>
<p>File uploads are an essential part of many web apps. LiveView has fantastic built-in support for <strong>uploading multiple files concurrently with progress updates</strong>.</p>
<p>We start by designing a reactive UI to select the files to upload, which includes:</p>
<ul>
<li>
<p>declaring auto-enforced constraints</p>
</li>
<li>
<p>rendering the form with interactive file selection</p>
</li>
<li>
<p>handling general and file-specific errors</p>
</li>
<li>
<p>showing an image preview and progress bar for each selected file</p>
</li>
<li>
<p>removing (kicking out) invalid or unwanted files</p>
</li>
<li>
<p>and yeah, we get fancy with drag and drop! 😎</p>
</li>
</ul>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/04/file-uploads-ui.jpg" width="600" />
</a>
</figure>
<h3 id="uploading-files-to-your-server">Uploading Files to Your Server</h3>
<p>With the UI ready to go, it’s time to upload some files! 📡 👀</p>
<p>We start by uploading to your Phoenix server and consuming the files so they’re associated with a record in the database. And by using PubSub to broadcast updates, <strong>everyone sees newly-uploaded images in real-time</strong>.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/04/file-uploads-server.jpg" width="600" />
</a>
</figure>
<h3 id="uploading-files-to-a-cloud-storage-service">Uploading Files to a Cloud-Storage Service</h3>
<p>Need to upload files to an external cloud-storage service? 🌤️ Not a problem. We switch things around to <strong>upload directly to Amazon S3</strong> while enforcing all the file constraints.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/04/file-uploads-cloud.jpg" width="600" />
</a>
</figure>
<p>✅ In the end, you’ll have a turn-key direct-to-server or direct-to-cloud solution that you can easily adapt to your own needs. And you’ll understand how it all works!</p>
<h3 id="finish-the-course-or-get-started-today">Finish the course, or get started today!</h3>
<p>If you already own the course (thank you!), just head over to <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro" target="_blank">the course</a> and you’ll find the new modules waiting for you!</p>
<p>Or if you’ve been waiting for the course to be 100% complete before picking up your copy, it’s now ready for you! We distilled everything you need to know about LiveView, assembled it in the right order, and neatly packaged it as a video course that’s paced for experienced, gotta-get-it-done developers like you. 🙌</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/liveview-new-improved.png" width="400" />
</a>
</figure>
<p>We sincerely appreciate all your support as we’ve completely updated this course for the very latest versions of Phoenix and LiveView.</p>
<p>We hope you enjoy it!</p>
LiveView Course Update #6: JS Commands, JS Hooks, and Key EventsThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/03/31/liveview-2ed-course-update-62023-03-31T00:00:00Z2023-03-31T00:00:00Z<p>We’re on the home stretch of wrapping up early access to our <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">Phoenix LiveView</a> course! Today we added 5 new videos…</p>
<h3 id="javascript-commands-">JavaScript Commands 🛒</h3>
<p>Sometimes you need a client-side effect: toggle visibility, add or remove CSS classes, transition using animations, and so on. Typically you’d do that with a dash of custom JavaScript. But with JS Commands, you can get the same effect without actually writing JavaScript. Plus changes made by JS Commands are preserved across patches from the server.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/js-commands.jpg" width="600" />
</a>
</figure>
<h3 id="javascript-hooks-">JavaScript Hooks 🪝</h3>
<p>Want to invite your favorite JavaScript library to the party? LiveView has excellent support for JavaScript interop. In this project we hook a JS calendar library into a LiveView so they work together seamlessly. Given what you learn in this project, you can get any JS library to play well with a LiveView!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/js-hooks.jpg" width="600" />
</a>
</figure>
<h3 id="key-events-">Key Events 🤹♀️</h3>
<p>LiveView has first-class support for key events, making it easy to support keyboard shortcuts, hot keys, and the like. To show you how it’s done and have some fun along the way, in this project we bring a lil’ juggler to life by directing his actions with a variety of key events.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/key-events.jpg" width="600" />
</a>
</figure>
<h3 id="how-do-i-get-the-new-course-modules">How do I get the new course modules?</h3>
<p>If you purchased the previous Pro version of the course, go to your <a href="https://pragmaticstudio.com/my_account" target="_blank">account dashboard</a> and click the big green “REDEEM” button to get the new Pro course for free. Or, if you’ve already done that, just head over to <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro" target="_blank">the course</a> and you’ll find the new modules ready for you!</p>
<p>Don’t yet own the Pro course? What are you waiting for? You can do amazing things with LiveView! And there’s still time to <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">get the Pro course</a> at the early access price, but time is running out!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/liveview-new-improved.png" width="400" />
</a>
</figure>
<p>Stay tuned for the final round of videos where we upload files to a cloud storage service! 🌤️</p>
LiveView Course Update #5: Live Auth, Sessions, and PresenceThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/03/22/liveview-2ed-course-update-52023-03-22T00:00:00Z2023-03-22T00:00:00Z<p>Robust authentication! Multi-user, real-time presence updates! You’d settle for nothing less in today’s web apps, right? 😉</p>
<p>So you’ll love this week’s round of 5 new videos in our <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">Phoenix LiveView</a> course…</p>
<h3 id="authenticating-liveviews">Authenticating LiveViews</h3>
<p>How does authentication work when it comes to LiveView and websocket connections? For starters, you need a secure session-based authentication system that has all the standard features: register, log in, log out, and so on. And thankfully Phoenix has a built-in generator to add a full-featured authentication system right into your app. We walk through the relevant code and then use it to seamlessly and securely authenticate LiveViews.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/live-auth.jpg" width="600" />
</a>
</figure>
<h3 id="live-sessions">Live Sessions</h3>
<p>You often want to enforce the same authentication policy across a group of live routes. That’s where live sessions come in super handy. And LiveView has special optimizations for live navigating between LiveViews in the same live session. You won’t want to miss these pro-level design and performance techniques!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/live-sessions.jpg" width="600" />
</a>
</figure>
<h3 id="presence-tracking">Presence Tracking</h3>
<p>Presence tracking is typically a DIY project. Not so with Phoenix! It has unrivaled, built-in presence tracking that uses PubSub to broadcast presence updates in real-time. We combine it with LiveView to build a fun yet real-world application.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/presence.jpg" width="600" />
</a>
</figure>
<h3 id="new-minor-phoenix-release">New Minor Phoenix Release</h3>
<p>Phoenix 1.7.2 was released earlier this week. This minor release doesn’t affect any code we’ve written in the videos or any of the exercises so far.</p>
<p>However, you will need to download the latest code bundle for what’s coming next. See the <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro/extras/early-access-changes" target="_blank">update steps</a> for steps on updating your app.</p>
<h3 id="how-do-i-get-the-new-course-modules">How do I get the new course modules?</h3>
<p>If you purchased the previous Pro version of the course, go to your <a href="https://pragmaticstudio.com/my_account" target="_blank">account dashboard</a> and click the big green “REDEEM” button to get the new Pro course for free. Or, if you’ve already done that, just head over to <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro" target="_blank">the course</a> and you’ll find the new modules ready for you!</p>
<p>Don’t yet own the Pro course? What are you waiting for? You can do amazing things with LiveView! And there’s still time to <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">get the Pro course</a> at the early access price, but time is running out!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/liveview-new-improved.png" width="400" />
</a>
</figure>
<p>Next up we dive into JavaScript commands and hooks! 🪝</p>
LiveView Course Update #4: Live Components and Real-Time UpdatesThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/03/15/liveview-2ed-course-update-42023-03-15T00:00:00Z2023-03-15T00:00:00Z<p>Today we added 2 new modules (3 videos) to our <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">Phoenix LiveView</a> course on designing Live Components and using Phoenix PubSub to broadcast real-time updates to multiple LiveViews. 📡</p>
<h3 id="live-components">Live Components</h3>
<p>In addition to function (stateless) components, LiveView also has live (stateful) components. They have their own state, handle their own events, and render independent of their parent LiveView. We build a live component step-by-step so you understand how they work, when and why to use them, and how they communicate with their parent LiveView.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/live-components.jpg" width="600" />
</a>
</figure>
<h3 id="real-time-updates">Real-Time Updates</h3>
<p>You don’t have to jump through a bunch of hoops to update LiveViews in real-time across multiple browser sessions. Phoenix PubSub makes it super easy to broadcast messages from the server to multiple LiveViews. To cap off the volunteers project, we use PubSub to keep everything in sync!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/real-time-updates.jpg" width="600" />
</a>
</figure>
<h3 id="how-do-i-get-the-new-course-modules">How do I get the new course modules?</h3>
<p>If you purchased the previous Pro version of the course, go to your <a href="https://pragmaticstudio.com/my_account" target="_blank">account dashboard</a> and click the big green “REDEEM” button to get the new Pro course for free. Or, if you’ve already done that, just head over to <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro" target="_blank">the course</a> and you’ll find the new modules ready for you!</p>
<p>Don’t yet own the Pro course? What are you waiting for? You can do amazing things with LiveView! And there’s still time to <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">get the Pro course</a> at the early access price:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/liveview-new-improved.png" width="400" />
</a>
</figure>
<p>Next up is authentication and live sessions! 🕵️♀️</p>
LiveView Course Update #3: Live Ecto Forms, Validations, Streams, and More!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/03/08/liveview-2ed-course-update-32023-03-08T00:00:00Z2023-03-08T00:00:00Z<p>We hope you’re enjoying early access to our <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">Phoenix LiveView</a> course! Today we added 5 new videos that are now ready for you…</p>
<h3 id="live-ecto-forms-and-lists">Live Ecto Forms and Lists</h3>
<p>Here’s a common thing you need to do: pop some data in a form, submit it to create a record in the database, and dynamically add the new thing to a list. By combining LiveView and Ecto, we have a powerful duo for handling all this server-side without any full page reloads.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/live-forms.jpg" width="600" />
</a>
</figure>
<h3 id="live-validations">Live Validations</h3>
<p>How do you validate form data on the fly? By combining Ecto changesets with the real-time performance of LiveView, we can use all the server-side validations to give instant feedback to the user. It’s one unified code base, so there’s no need for separate client-side validations.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/live-validations.jpg" width="600" />
</a>
</figure>
<h3 id="streams">Streams</h3>
<p>LiveView is chock full of optimizations! When you need to efficiently manage large collections of items in a stateful LiveView process, streams is the ticket. Stream items are temporary: they’re freed from LiveView’s state as soon as they’re rendered. We use streams to dynamically add, update, and delete items on the client without the overhead of keeping them on the server.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/streams.jpg" width="600" />
</a>
</figure>
<h3 id="toggling-state">Toggling State</h3>
<p>Pending or approved? Draft or published? Shipped or delivered? You often need a UI element that dynamically toggles a bit of state without triggering a full page update. We’ll show you how to do it lickety-split the LiveView way without a stitch of JavaScript. 😀</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/03/toggling-state.jpg" width="600" />
</a>
</figure>
<h3 id="new-minor-phoenix-release">New Minor Phoenix Release</h3>
<p>Phoenix 1.7.1 was released a few days ago. The difference between Phoenix 1.7.0 and 1.7.1 is you can now render Heroicons using a function component. And, to optimize their usage, the Heroicons are embedded in the app.css bundle. 🦸</p>
<p>This new feature doesn’t affect any code we’ve written in the videos or any of the exercises so far. However, in upcoming course modules we’ll use the new function component when rendering Heroicons.</p>
<p>So if you’ve already started the course and downloaded the code bundle, you’ll want to download the latest code bundle which has been updated for Phoenix 1.7.1. Then to bring the application you already have in step with Phoenix 1.7.1, follow the <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro/extras/early-access-changes" target="_blank">update steps</a> we put together for you.</p>
<h3 id="how-do-i-get-the-new-course-modules">How do I get the new course modules?</h3>
<p>If you purchased the previous Pro version of the course, go to your <a href="https://pragmaticstudio.com/my_account" target="_blank">account dashboard</a> and click the big green “REDEEM” button to get the new Pro course for free. Or, if you’ve already done that, just head over to <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro" target="_blank">the course</a> and you’ll find the new modules ready for you!</p>
<p>Don’t yet own the Pro course? What are you waiting for? You can do amazing things with LiveView! And there’s still time to <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">get the Pro course</a> at the early access price:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/liveview-new-improved.png" width="400" />
</a>
</figure>
<p>Next up, we’ll dive into Live Components and real-time updates using Phoenix PubSub. 🚀</p>
LiveView Course Update #2: Live Nav, Sorting, and PaginationThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/02/23/liveview-2ed-course-update-22023-02-23T00:00:00Z2023-02-23T00:00:00Z<p>We hope you’re enjoying early access to our <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">Phoenix LiveView</a> course! Today we added three new videos that are now ready for you…</p>
<h3 id="live-navigation">Live Navigation</h3>
<p>Page navigation with LiveView is really sweet. It’s faster than your typical single-page application in part because of the over-the-wire data optimizations. And it’s far simpler to implement as compared to the complexity of a client-side JavaScript framework. We see two ways to do live navigation and also how to handle changing URL parameters.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/live-nav.jpg" width="600" />
</a>
</figure>
<h2 id="sorting">Sorting</h2>
<p>No page of tabular data is complete without links for sorting each column. And of course you also want the sorting options to be preserved in the URL so bookmarked pages show consistent results. No worries, we’ll help you sort out (sorry!) how to do that using everything we learned about live navigation.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/sorting.jpg" width="600" />
</a>
</figure>
<h2 id="pagination">Pagination</h2>
<p>Pagination is a must-have for most applications. And navigating between pages of Ecto records is super-zippy thanks to live navigation and the raw power of Phoenix. You can adapt the techniques you learn to lots of different scenarios in your own apps. Plus, there’s pizza involved.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/pagination.jpg" width="600" />
</a>
</figure>
<h3 id="how-do-i-get-the-new-course-modules">How do I get the new course modules?</h3>
<p>If you purchased the previous Pro version of the course, go to your <a href="https://pragmaticstudio.com/my_account" target="_blank">account dashboard</a> and click the big green “REDEEM” button to get the new Pro course for free. Or, if you’ve already done that, just head over to <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro" target="_blank">the course</a> and you’ll find the new modules ready for you!</p>
<p>Don’t yet own the Pro course? What are you waiting for? You can do amazing things with LiveView! And there’s still time to <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">get the Pro course</a> at the early access price:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/liveview-new-improved.png" width="400" />
</a>
</figure>
<p>We’re already working on the next batch of videos covering LiveView forms that validate and save Ecto records to the database, and the new streams feature for efficiently handling large collections.</p>
<p>Thanks again for following along with us. We hope you’re having a blast with LiveView! 🚀</p>
LiveView Course Update #1: Filtering and Function ComponentsThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/02/16/liveview-2ed-course-update-12023-02-16T00:00:00Z2023-02-16T00:00:00Z<p>We’re back with an update about our <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">Phoenix LiveView</a> course! 🔥</p>
<p>Here’s what’s new this week…</p>
<h3 id="filtering">Filtering</h3>
<p>How would you build a LiveView that filters data stored in an Ecto repo based on dynamically-changing filter criteria? The user ticks a box or changes an option and boom! the page updates with results.</p>
<p>We show you exactly how to build it, and you can easily adapt this project to suit your own filtering needs. We finally put something in the database, and we tossed in a hot performance tip!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/filtering.jpg" width="600" />
</a>
</figure>
<h2 id="function-components">Function Components</h2>
<p>Components, components, components! Once you know how to make them, you’ll find lots of opportunities to restructure LiveViews into reusable, easy-to-maintain components. We make a function component with declarative assigns and slots, and also extract a few function components from an existing LiveView to improve the overall design.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/function-components.jpg" width="600" />
</a>
</figure>
<h2 id="using-tailwind-css-with-phoenix-17">Using Tailwind CSS with Phoenix 1.7</h2>
<p>Some of you have asked how we set up <a href="https://tailwindcss.com" target="_blank">Tailwind CSS</a> in the Phoenix 1.7 application in the course. We heard ya. 👍</p>
<p>Check out our <a href="https://pragmaticstudio.com/tutorials/using-tailwind-css-in-phoenix" target="_blank">Using Tailwind CSS in Phoenix 1.7</a> tutorial for all the details. We also added a link to this tutorial in the course notes, for future reference.</p>
<h3 id="how-do-i-get-the-new-course-modules">How do I get the new course modules?</h3>
<p>If you purchased the previous Pro version of the course, go to your <a href="https://pragmaticstudio.com/my_account" target="_blank">account dashboard</a> and click the big green “REDEEM” button to get the new Pro course for free. Or, if you’ve already done that, just head over to <a href="https://online.pragmaticstudio.com/courses/liveview-2ed-pro" target="_blank">the course</a> and you’ll find the new modules ready for you!</p>
<p>Don’t yet own the Pro course? What are you waiting for? You can do amazing things with LiveView! And there’s still time to <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">get the Pro course</a> at the early access price:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/liveview-new-improved.png" width="400" />
</a>
</figure>
<p>We hope you’re enjoying the course so far! 😃</p>
LiveView Course Updated and Available in Early AccessThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2023/02/07/liveview-2ed-early-access-opens2023-02-07T00:00:00Z2023-02-07T00:00:00Z<p>Our <a href="https://pragmaticstudio.com/phoenix-liveview" target="_blank">Phoenix LiveView course</a> has been updated and is now available in early access! 🎉</p>
<p>It’s been <strong>completely redesigned, top-to-bottom for LiveView 0.18 and Phoenix 1.7</strong>. Plus we’ve added brand new sections on HEEx templates, function and live components, declarative assigns, slots, live sessions, presence tracking, JS Commands, and more.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2023/02/liveview-new-improved.png" width="400" />
</a>
</figure>
<p>You’re gonna love how the latest versions of Phoenix and LiveView simplify and unify everything! 😄 And this course will help you build LiveView apps like a pro with:</p>
<ul>
<li><strong>real-world mini-projects</strong> that solve a variety of common challenges</li>
<li><strong>practical techniques</strong> you can immediately apply to your own projects</li>
<li><strong>super-clear explanations</strong> so you get good mental models</li>
</ul>
<p>We distilled everything you need to know about LiveView, assembled it in the right order, and neatly packaged it as a video course that’s paced for experienced, gotta-get-it-done developers just like you. 🙌</p>
<h3 id="whats-in-early-access">What’s In Early Access?</h3>
<p><strong>Instant access</strong> to the first 8 modules of the course. It’s practical stuff you can use right away!</p>
<p>Then every week or so after that (or as soon as we get them ready) we’ll roll out the next batch. That way you can incrementally knock out a few modules at a time until the course is 100% complete in March.</p>
<p>👉 Check out the <a href="https://pragmaticstudio.com/phoenix-liveview#outline" target="_blank">full course outline</a>.</p>
<h3 id="its-a-free-update-if-you-own-the-previous-pro-course">It’s a free update if you own the previous Pro course.</h3>
<p>Yup, you read that right. Simply go to your <a href="https://pragmaticstudio.com/my_account" target="_blank">account dashboard</a> and click the big green “REDEEM” button to get the new Pro course. (Don’t worry, you’ll still have access to the previous course.) Thank you for being an early adopter and supporting the course!</p>
<p>This being a free update and all, some of you recently asked about making a donation. (Wow, y’all are wonderful! 🧡) We consume copious amounts of coffee and tea in the Studio, so you could always <a href="https://www.buymeacoffee.com/mikeandnicole" target="_blank">buy us a cup</a>. ☕️😋</p>
<h3 id="what-you-dont-own-the-pro-course-">What, you don’t own the Pro course? 😲</h3>
<p>Why not give it a try? You can do amazing things with LiveView!</p>
<p>Imagine building multi-user, real-time, interactive web apps with Elixir rather than JavaScript. There’s so much already built in to Phoenix that <strong>you’ll be amazed at all the things you don’t have to do</strong>. Indeed, nothing stacks up to this stack. 🚀</p>
<p>And we’re obviously biased, but we think our course is the quickest, most approachable way to get up to speed on LiveView. There’s no monthly subscription or time limit. You own it for life.</p>
<p>Want a deal? We offer <a href="https://pragmaticstudio.com/courses/phoenix-liveview#buy" target="_blank">generous pro bundle and team discounts</a>.</p>
<h3 id="know-anyone-with-js-fatigue">Know anyone with JS fatigue?</h3>
<p>We’d love to help them increase their developer happiness with LiveView. 😉 It would mean a lot to us if you could take a second to give a shout-out about this course to a friend, in a tweet, on a forum, or wherever you hang out.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/courses/liveview-large.png" width="400" />
</a>
</figure>
Rails 7 Course Update and What's NextThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2022/08/15/rails7-course-update2022-08-15T00:00:00Z2022-08-15T00:00:00Z<figure>
<img src="/images/blog/2022/08/beaver-roller-coaster.jpg" width="400" />
</figure>
<p>Knock knock!</p>
<p><em>Who’s there?</em></p>
<p>Beaver!</p>
<p><em>Beaver who?</em></p>
<p>Beaver-y quiet, I’m hiding!</p>
<p>😂</p>
<p>Yeah, you probably thought we were hiding this summer. But noooooo, we’ve been busy as beavers updating a couple courses.</p>
<p><strong>Today we’re excited to announce that our popular <a href="https://pragmaticstudio.com/courses/rails">Ruby on Rails course</a> has been entirely updated for Rails 7!</strong></p>
<p>Thanks for your patience with this. It’s been a massive effort, despite the changes being relatively trivial. The thing about video is that it’s totally unforgiving when it comes to even minor syntax changes. In an 8-hour course like this, small changes have big ripple effects.</p>
<p>Anywho…</p>
<p>🦫 We understand that trendy beavers may be hesitant to dive into Rails waters, claiming it’s too main-stream. But really, water you waiting for? It’s not like the job market is over-saturated. And Rails 7 with Hotwire is like no otter. So go with the flow…</p>
<h3 id="new-to-rails-or-just-need-a-refresher-we-gotchu">New to Rails, or just need a refresher? We gotchu.</h3>
<p>In this <a href="(https://pragmaticstudio.com/courses/rails)">comprehensive course</a> you’ll learn all the fundamentals of Rails by building a complete application from scratch. The full course includes:</p>
<ul>
<li>
<p><strong>54 carefully-crafted videos</strong> (all with English subtitles)</p>
</li>
<li>
<p><strong>45 animations</strong> to visualize all the key concepts and get a solid mental model for how everything fits together</p>
</li>
<li>
<p><strong>52-chapter workbook</strong> (with exercises) where you build a different app than in the videos</p>
</li>
<li>
<p><strong>Starter files</strong> and versions of the code for each video and exercise</p>
</li>
<li>
<p>The final source code for <strong>2 full-featured Rails applications</strong></p>
</li>
</ul>
<figure>
<a href="https://pragmaticstudio.com/courses/rails">
<img src="/images/courses/rails7-large.png" width="400" />
</a>
</figure>
<h3 id="bought-the-previous-version-of-the-course-free-update-for-you">Bought the previous version of the course? Free update for you!</h3>
<p>Yup, you read that right. If you own the Rails 6 course, you get the Rails 7 course for free. 🙌</p>
<p>Simply go to your <a href="https://pragmaticstudio.com/my_account">account dashboard</a> and click the big green “REDEEM” button. You’ll still have access to your Rails 6 course, plus you’ll get this updated course.</p>
<h3 id="if-you-already-took-the-rails-6-course-do-you-need-to-retake-this-rails-7-course">If you already took the Rails 6 course, do you need to retake this Rails 7 course?</h3>
<p>Probably not, unless you’ve been away from Rails for a while and need a refresher. Because here’s the thing: 98.7% of what’s in the Rails 6 course is exactly the same in the Rails 7 course. Indeed, in terms of the fundamentals taught in this course, very little has changed in Rails 7. Yeah for stable software! 👍</p>
<p>So, instead of re-watching 8 hours of video to spot the tiny diffs, check out the <a href="https://online.pragmaticstudio.com/courses/rails7/extras/rails7_changes">summary of minor syntax changes</a> we put together for you.</p>
<p>And save your time for…</p>
<h3 id="hotwire-its-the-big-new-shiny-thing-in-rails-7">Hotwire! It’s the big new shiny thing in Rails 7.</h3>
<p>And you need to know how to use it!</p>
<p>Hotwire is next-level stuff for improving the speed and responsiveness of your Rails apps. It lets you build modern, interactive Rails apps without jumping through all the JavaScript hoops. Instead, Hotwired apps are mostly server-rendered HTML. So everything you know (and love) about Rails is still in play.</p>
<p>Now, there’s no need to scour the web and waste your time piecing together resources for learning Hotwire. We distilled everything you need to know in our <a href="https://pragmaticstudio.com/hotwire-rails">Hotwire for Rails Developers</a> course. It’s designed specifically for busy Rails devs, just like you. 👊</p>
<p>We start with a typical Rails app and incrementally add Hotwire to turbo-charge each page. 🏎 (Check out the <a href="https://gone-fishing-studio.herokuapp.com">final app</a>.) By the end, you’ll know exactly how to integrate each facet of Hotwire into your own apps without breaking stuff.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/courses/hotwire-large.png" width="400" />
</a>
</figure>
<h3 id="whats-next-">What’s Next? 👀</h3>
<p>An update to our <a href="https://pragmaticstudio.com/courses/phoenix-liveview">Phoenix LiveView</a> course… we hope!</p>
<p>LiveView has had some significant changes already and more are in the works.</p>
<p>We’ve actively been redesigning the course to take advantage of all the latest LiveView features, and we’re really excited to share them with you. Unfortunately it’s just not practical for us to re-film for every version release given how fluid LiveView development has been as of late.</p>
<p>Hopefully the next version will solidify a lot of things and we can start re-filming soon. 🤞</p>
<p>And yup, it’ll be a <strong>free update if you already bought the course</strong>.</p>
<p>In the meantime, we hope you enjoy the Rails 7 and Hotwire courses!</p>
Hotwire Course Officially Launches!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2022/04/19/hotwire-course-launches2022-04-19T00:00:00Z2022-04-19T00:00:00Z<p>Howdy again, everyone. 👋</p>
<p>Today we released 3 new modules (4 new videos) and we’re excited to announce that our <a href="https://pragmaticstudio.com/courses/hotwire-rails">Hotwire for Rails Developers</a> course is now content-complete and out of early access! 🥳</p>
<p>The 3 new modules are (drum roll 🥁):</p>
<h3 id="broadcasting-real-time-updates">Broadcasting Real-Time Updates</h3>
<p>Zip, zap, zooey! Real-time updates are expected in modern web apps. And with Hotwire, you don’t have to jump through a bunch of hoops to get in on the action. Zing! We <strong>broadcast Turbo Streams to keep an activity timeline in sync</strong> across multiple browsers.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/04/broadcasting-catches.jpg" width="600" />
</a>
</figure>
<h3 id="even-more-broadcasting">Even More Broadcasting!</h3>
<p>The more examples you see, the more experience you gain. And this app has a double whammy of real-life broadcasting features. In this extended example, we use both <strong>Turbo Frames and Streams to update a page differently depending on who’s viewing it</strong>.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/04/broadcasting-likes.jpg" width="600" />
</a>
</figure>
<h3 id="lazy-loading-content">Lazy-Loading Content</h3>
<p>Why load everything on a page from the get-go when you can fetch content lazily? One powerful aspect of Turbo Frames is they can be lazy-loaded. <strong>Leave your JavaScript at the door.</strong> After a basic example, we use this technique to implement infinite scrolling.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/04/lazy-loading.jpg" width="600" />
</a>
</figure>
<h3 id="finish-the-course-or-get-started-today">Finish the course, or get started today!</h3>
<p>If you already own the course (thank you!), you’ll find 4 new videos waiting <a href="https://online.pragmaticstudio.com/courses/hotwire">in your account</a>. Fresh bits, right out of a piping-hot video compressor!</p>
<p>Or if you’ve been waiting for the course to be 100% complete before picking up a copy, it’s now <a href="https://pragmaticstudio.com/courses/hotwire-rails">ready for you</a>! It’s around 3.5 hours of carefully crafted video covering all the facets of Hotwire in our homespun format. 😉</p>
<figure>
<a href="/hotwire-rails">
<img src="/images/courses/hotwire-large.png" width="400" />
</a>
</figure>
<p>We sincerely appreciate all your support as we’ve worked on this course these past several months.</p>
<p>We hope you all enjoy it!</p>
New Hotwire Video: Stimulus Targets, Values, and More!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2022/04/06/hotwire-course-update-stimulus2022-04-06T00:00:00Z2022-04-06T00:00:00Z<p>Want to invite your favorite JavaScript library to the Hotwire party? We thought you might! 😉</p>
<p>In the Gone Fishin’ app of our <a href="https://pragmaticstudio.com/courses/hotwire-rails">Hotwire for Rails Developers</a> course, we wanted a JS range slider library to filter catches, like this:</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/04/stimulus-values.jpg" width="600" />
</a>
</figure>
<p>Using a JS library gives us an opportunity to learn Stimulus in more depth with yet another real-life example. And this one involves a little of everything:</p>
<ul>
<li>lifecycle callbacks,</li>
<li>values,</li>
<li>targets, and</li>
<li>handling and dispatching custom events</li>
</ul>
<p>In this new video you’ll learn everything needed to integrate pretty much any JS library into your Hotwire app! If you already own the course, you’ll find the new video ready for you in your account.</p>
<h3 id="next-up">Next Up</h3>
<p>We’re working on videos for the 4th and final page of the app where we’ll dive deep into broadcasting real-time updates and infinite scrolling. Because no angler wants to miss out on the latest fishing activity. 🐟 😵 🐠</p>
<p>Enjoy!</p>
<figure>
<a href="/hotwire-rails">
<img src="/images/courses/hotwire-large.png" width="400" />
</a>
</figure>
More Hotwire VideosThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2022/03/17/hotwire-course-update-filter-sort2022-03-17T00:00:00Z2022-03-17T00:00:00Z<p>We added three new videos to our <a href="https://pragmaticstudio.com/courses/hotwire-rails">Hotwire for Rails Developers</a> course today!</p>
<p>Before we get into/to what’s new, first a HUGE thanks to everyone who has purchased the course during early access.</p>
<p>It’s about 2/3 complete at this point, and we’re grateful for all the support and encouraging feedback so far:</p>
<p><em>“The short practical examples are absolutely amazing!” – Thomas Van Holder</em></p>
<p><em>“I love the way you have simplified the whole Hotwire handbook.” – Sergio Alejandro Zaizar Fregoso</em></p>
<p><em>“It’s amazing! Love all the animations… and the example app is awesome!” – Tony Messias</em></p>
<p><em>“The explanations are awesome!” – Noah Stern</em></p>
<p><em>“The examples are cool, fun, and mirror real life applications.” – John Chambers</em></p>
<p>It’s also been humbling to hear that some of you discovered the blooper reels. 😂 Nicole loves to sneak those in.</p>
<p>On a more practical note (ahem!), many of you have asked about upgrading Rails 6 apps to use Hotwire. While Rails 7 apps use it by default, Hotwire works equally well in Rails 6 apps. We wrote up <a href="https://online.pragmaticstudio.com/courses/hotwire/extras/install_hotwire_rails6">some notes</a> on how to get everything installed and upgraded.</p>
<p>Last, but by no means least, quite a few of you asked for more examples using Stimulus. We gotchu. You’ll be pleased to know that we look at three more Stimulus examples in this week’s round of new videos. 🙌</p>
<h3 id="flash-messages">Flash Messages</h3>
<p>Once you start integrating Hotwire into your app, you’ll need to render flashes a bit differently than you’re used to. Using a Turbo Stream and a Stimulus controller, we <strong>animate flash messages the Hotwire way</strong>.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/03/flash-messages.jpg" width="600" />
</a>
</figure>
<h3 id="filtering-sorting-and-paginating-datatables">Filtering, Sorting, and Paginating Datatables</h3>
<p>Almost every app has tabular data that needs to be filtered, sorted, and paginated. Using the techniques we’ve learned so far (along with a few new tricks) we turbo-charge a datatable. That way, when you <strong>change the filter criteria or sort a column – boom! – the page dynamically updates</strong>. And we make sure the URL automatically updates so pages can be bookmarked. This example has you covered top to bottom!</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/03/filter-sort.jpg" width="600" />
</a>
</figure>
<h3 id="stimulus-targets--custom-turbo-events">Stimulus Targets + Custom Turbo Events</h3>
<p>The role of Stimulus is easily misunderstood. When do you reach for it? And how do you use Stimulus to complement what’s already possible with Turbo? The best way to answer these questions is to see Stimulus used in a variety of real-life examples. So here’s another one! And it deals with <strong>performing more complex operations when a page changes</strong>.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/03/stimulus-targets.jpg" width="600" />
</a>
</figure>
<h3 id="already-own-the-course">😁 Already own the course?</h3>
<p>Great – just <a href="https://online.pragmaticstudio.com/courses/hotwire">head over to the course</a> and you’ll find 3 new videos awaiting you! Please be sure to download a fresh copy of the code bundle which includes updates for the new videos.</p>
<h3 id="dont-have-your-copy-of-the-course-yet">🤔 Don’t have your copy of the course yet?</h3>
<p>There’s still time to take advantage of the <a href="(https://pragmaticstudio.com/courses/hotwire-rails)">early access price</a>. We think you’ll get a lot of value out of the 17 videos already in the course (what’s already in the course), and more videos are on the way. We’d love to have you aboard!</p>
<h3 id="next-up">Next Up</h3>
<p>Next up is yet another Stimulus example. This one’s a bit more sophisticated using targets and values to integrate an external JavaScript library. It’s likely something many of you will need to do in your own apps. 😉</p>
<p>Thanks for cruising along with us. 🐟 🐠 🐡</p>
<p>Enjoy!</p>
<figure>
<a href="/hotwire-rails">
<img src="/images/courses/hotwire-large.png" width="400" />
</a>
</figure>
Hotwire Course Update: Forms and ListsThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2022/02/24/hotwire-course-update-forms-lists2022-02-24T00:00:00Z2022-02-24T00:00:00Z<p>We have 5 new Hotwire videos for you this week!</p>
<p>😁 If you’ve already purchased a copy of the course (thanks!), just <a href="https://online.pragmaticstudio.com/courses/hotwire" target="_blank">head over to the course</a> and you’ll find 5 new videos ready for you! Make sure to download a new copy of the code bundle which includes directories for the new modules.</p>
<p>🤔 Don’t have your copy of the course yet? There’s still time to <a href="https://pragmaticstudio.com/courses/hotwire-rails" target="_blank">take advantage of the early access price</a>. We think you’ll get a lot of value out of what’s already in the course, and more videos are on the way. We’d love to have you aboard.</p>
<p>The latest batch of videos take us through hotwiring the <a href="https://gone-fishing-studio.herokuapp.com/tackle_box_items" target="_blank">second page</a> of our lil’ fishing app. We build on what we’ve already learned about Turbo Frames and Streams, but apply them in new situations.</p>
<h3 id="forms-and-lists">Forms and Lists</h3>
<p>Here’s a common scenario: pop some data into a form, submit it to create a record in the database, and dynamically add the new thing to a list. Using Turbo Streams we can <strong>efficiently append and prepend elements to a list</strong> without changing the existing contents. And as a bonus, we also update totals on another part of the page.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/02/forms-lists.jpg" width="600" />
</a>
</figure>
<h3 id="handling-form-errors">Handling Form Errors</h3>
<p>How do you display validation errors on a form with Hotwire? <strong>Inline and instantly, of course!</strong> And since everything is server-rendered in one unified code base, we can reuse all the ActiveRecord model validations already set up to ensure data integrity.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/02/form-errors.jpg" width="600" />
</a>
</figure>
<h3 id="dynamic-deletes">Dynamic Deletes</h3>
<p>One of the compelling benefits of Hotwire is that it makes easy things easy. You know, things like <strong>dynamically zapping an item from a list</strong>. Whereas historically you may have written custom JavaScript to keep everything on the page in sync, now we can use Turbo Streams.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/02/dynamic-deletes.jpg" width="600" />
</a>
</figure>
<h3 id="inline-form-editing">Inline Form Editing</h3>
<p>When do you use Turbo Frames vs. Turbo Streams, and why? Inline editing is a great example for working through these types of design decisions. In this case, we end up using both and you understand the interplay between them. The takeaway is a <strong>clear mental model and nifty technique</strong> you can apply with confidence.</p>
<figure>
<a href="https://pragmaticstudio.com/courses/hotwire-rails">
<img src="/images/blog/2022/02/inline-editing.jpg" width="600" />
</a>
</figure>
<p>Enjoy!</p>
<figure>
<a href="/hotwire-rails">
<img src="/images/courses/hotwire-large.png" width="400" />
</a>
</figure>
Hotwire Course Early Access is OpenThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2022/02/02/hotwire-early-access-opens2022-02-02T00:00:00Z2022-02-02T00:00:00Z<p>Big news: <a href="https://pragmaticstudio.com/hotwire-rails" target="_blank">Hotwire for Rails Developers</a> is now available in early access! 🎉</p>
<p>And we think it’s gonna forever change how you develop Rails frontends. Why? Simple: you no longer need to climb the JavaScript mountain to build modern, dynamic frontends with Rails.</p>
<p>Hotwire gives you a practical, no-nonsense alternative that makes you the hero without any of the heroic efforts. Plus it’s baked right into Rails 7, and yet works equally well in Rails 6 apps.</p>
<p>This course shows you exactly how to use Hotwire to improve the speed and responsiveness of a real Rails app. No hype or hand-waving here.</p>
<h3 id="why-early-access">Why Early Access?</h3>
<p>Simply put, because Rails 7 is out and a <strong>ton</strong> of you have expressed interest in this course.</p>
<p>Every day we get emails and Twitter DMs like “I need this NOW! What’s the ETA?”</p>
<p>Well good news, y’all. With what’s in Early Access, you’ll learn all the facets of Hotwire… today! No need to wait for the course to be 100% complete.</p>
<h3 id="whats-in-early-access">What’s in Early Access?</h3>
<p>Quite a lot, actually!</p>
<p>We didn’t really plan to cover so much so early. But the structure of this course is different.</p>
<p>A typical course might start with a basic use of Turbo Drive and (hours later) end with an advanced use of Stimulus.</p>
<p>However, we start with a traditional Rails app and, going page by page, we apply various aspects of Hotwire. The app has 4 pages showcasing a wide range of common UI scenarios. And it turned out that the first page alone benefits from a little bit of everything:</p>
<ul>
<li>
<p>Turbo Drive to speed up page navigation</p>
</li>
<li>
<p>Turbo Frames to dynamically update part of the page</p>
</li>
<li>
<p>Turbo Streams to modify multiple elements on the page (without writing JavaScript 😉)</p>
</li>
<li>
<p>And even Stimulus for a search-as-you-type feature</p>
</li>
</ul>
<p>Wowza!</p>
<h3 id="the-first-page-alone-is-a-mini-project-">The first page alone is a mini-project. 🏗</h3>
<p>It covers a lot of bases. And it’s a great introduction to how everything works and fits together.</p>
<p>Combine that with the right mental models you’ll pick up from the animations and behind-the-scenes looks, and you’ll be able to immediately start slipping Hotwire into your pages.</p>
<h3 id="and-thats-just-the-beginning">And that’s just the beginning</h3>
<p>There’s more coming!</p>
<p>In upcoming weeks we’ll release new course modules on everything from filtering datatables to pagination to realtime updates and beyond. It’s fun and practical stuff you can use in any app! 🚀</p>
<p>👉 Check out the <a href="https://pragmaticstudio.com/hotwire-rails#outline" target="_blank">full course outline</a>.</p>
<h3 id="scoop-it-up-at-a-limited-time-price">Scoop it up at a limited-time price</h3>
<p>If just one video, code snippet, tip, or technique saves you an hour of time, then it’s totally worth it! We’ve done all the work and research for you. 🤓</p>
<p><strong>Start the course today to see how to integrate Hotwire into a real-world app without breaking stuff.</strong></p>
<figure>
<a href="/hotwire-rails">
<img src="/images/courses/hotwire-large.png" width="400" />
</a>
</figure>
We "hotwired" a Rails app. Want to see how?The Pragmatic Studiohttps://pragmaticstudio.com/blog/2021/08/10/want-a-rails-hotwire-course2021-08-10T00:00:00Z2021-08-10T00:00:00Z<figure>
<img src="/images/blog/2021/08/torch-rails-train.jpg" width="600" />
</figure>
<p>We’re considering cranking up a new course… and <strong>we need your help!</strong></p>
<p>You know we’re big fans of both Ruby/Rails and Elixir/Phoenix. They each have their place depending on various project and people factors. And it’s always good to have options.</p>
<p>Last year we leaned heavily into Phoenix and created an in-depth (and popular!) <a href="https://pragmaticstudio.com/courses/phoenix-liveview" target="_blank">LiveView course</a>. And about the time we were wrapping up that course, <a href="https://hotwired.dev" target="_blank">Hotwire</a> arrived on the Rails scene. Hotwire is to Rails what LiveView is to Phoenix.</p>
<p>So we started looking at how to use Hotwire in our Rails apps. You may not know that our entire business runs on Rails, and has for the past 15 years. And we identified a couple areas that we wanted to “hotwire”.</p>
<p>But we stalled out…</p>
<h3 id="initially-hotwire-didnt-click-for-us-and-that-felt-frustrating">Initially Hotwire didn’t “click” for us and that felt frustrating!</h3>
<p>It wasn’t because the fundamental concepts were tricky to understand. Conceptually, Hotwire is fairly straightforward. It lets you dynamically update parts of a page in response to user interactions without writing JavaScript.</p>
<p>It’s is a pragmatic alternative to the complexity of building single-page apps. And, no surprise, we love pragmatic solutions!</p>
<p>But we were puzzled with how to use Hotwire in practice.</p>
<ul>
<li>
<p>What’s the diff between Turbo Drive, Turbo Frames, and Turbo Streams?</p>
</li>
<li>
<p>Where does Stimulus fit in?</p>
</li>
<li>
<p>When do you use one versus the other, and why?</p>
</li>
<li>
<p>How do you incrementally enhance an existing Rails app to take advantage of Hotwire?</p>
</li>
</ul>
<h3 id="to-answer-these-and-other-questions-we-did-what-we-always-do">To answer these and other questions, we did what we always do.</h3>
<p>We hunkered down and hammered through it. 🤓 That involved weeks of research, a bunch of back-of-the-napkin sketches, and experimenting with lots of code.</p>
<h3 id="then-we-hotwired-a-rails-app">Then we “hotwired” a Rails app.</h3>
<p>No, not our production app. It has waaay too much code to work around when we’re in “learning” mode, not to mention being critical to the business. We much prefer learning with a small, carefree application. A safe environment where we could really kick the tires and throw caution to the wind.</p>
<p>And it just so happens we had such an app sitting on the shelf. So we upgraded it to Rails 6, gave it a little polish, and worked through how to add facets of Hotwire one page at a time.</p>
<p>Along the way there was plenty of head scratching, troubleshooting, and refactoring. You know how it goes, yeah? Lots of trial and error. 🤪 But in the end we were really pleased with the results.</p>
<h3 id="and-we-learned-a-ton">And we learned a ton!</h3>
<p>Now we can enthusiastically say, “Aha, we get it!” With a good mental model for how Hotwire works, everything “clicks” together.</p>
<p>Better yet, we know when, where, why, and how to use it with confidence.</p>
<p>So we’re ready to start using Hotwire in our Studio apps. 🙌</p>
<h3 id="are-you-in-the-same-boat-we-were">Are you in the same boat we were?</h3>
<p>You’ve heard about Hotwire but you’re frustrated by having a lot of unanswered (and important) questions:</p>
<ul>
<li>
<p>What is it?</p>
</li>
<li>
<p>How do the major parts of Hotwire fit together?</p>
</li>
<li>
<p>Why and when would I use it?</p>
</li>
<li>
<p>How does it work?</p>
</li>
<li>
<p>Is it a substitute for using React, Vue, or other JS?</p>
</li>
<li>
<p>If it’s so cool, how do I take full advantage of it?</p>
</li>
</ul>
<p>😫 😫 😫</p>
<h3 id="imagine-skipping-the-sour-face-and-going-straight-to-the-sweet-spot">Imagine skipping the sour face and going straight to the sweet spot.</h3>
<p>For reals? You betcha.</p>
<p>We have an example application and an outline for a course that will teach you Hotwire (and help answer these questions) without swallowing up enormous amounts of your time.</p>
<p>Hotwire isn’t a completely new way to write Rails apps. It builds on skills you already have. Everything you know about Rails is still in play. Hotwire just brings new tricks to the game. ✨</p>
<p>So by assuming you already know Rails – and we have a comprehensive <a href="https://pragmaticstudio.com/courses/rails" target="_blank">Rails course</a> for that – it’ll only take a couple hours to learn Hotwire.</p>
<p>😀 😀 😀</p>
<h3 id="yeah-with-the-right-course-you-can-learn-hotwire-lickety-split">Yeah, with the right course, you can learn Hotwire lickety-split!</h3>
<p>Basically, we’d distill everything we learned into a compact, clear set of videos and notes for you.</p>
<p>The course would start with the big picture of Hotwire and then break down the concepts. Without a good mental model, Hotwire can be puzzling (or at least it was for us).</p>
<p>Then we’d make the concepts concrete by applying them step-by-step to the Rails app we used to learn Hotwire. In our usual style of animations, super clear explanations, and live coding, you’d see how to incrementally add Hotwire to an existing Rails app.</p>
<p>You’d come away with a solid understanding of how Hotwire works, along with ideas and examples for adding it to your Rails apps.</p>
<p>Imagine learning (in hours, not days) how to increase the speed and responsiveness of your apps through incremental enhancements. 🚀</p>
<h3 id="would-you-dig-a-course-like-that">Would you dig a course like that?</h3>
<p>If so, please let us know by adding your name to our Hotwire-specific mailing list. That way we can notify you if we green-light the course, and send you progress updates along the way. Don’t worry, you can unsubscribe at any time. Thanks!</p>
<div class="sm:max-w-lg sm:mx-auto rounded-lg p-6 bg-gray-100">
<div class="text-xl text-center font-bold text-gray-600">
Yup, I dig that!
</div>
<form class="js-cm-form flex items-center mt-6 space-y-4 flex-col sm:flex-row sm:space-y-0 sm:space-x-4" id="subForm" action="https://www.createsend.com/t/subscribeerror?description=" method="post" data-id="191722FC90141D02184CB1B62AB3DC2637E4C7FAFA0AC798C4B5C2F86DF221D2BEB22DE3598C2A4F0C3D1EEC35327496BADB261A0884D20576D88918C86D3798">
<input autocomplete="Email" aria-label="Email" class="js-cm-email-input qa-input-email shadow-sm rounded-lg relative block border-gray-400 text-gray-900 focus:outline-none focus:ring-1 focus:ring-green-500 focus:border-green-500 focus:z-10 w-full" id="fieldEmail" maxlength="200" name="cm-yujlikd-yujlikd" required="" type="email" placeholder="Your Email..." />
<input id="cm-privacy-email-hidden" name="cm-privacy-email-hidden" type="hidden" value="true" />
<button type="submit" class="w-full sm:w-auto text-white bg-green-700 hover:bg-green-600 active:bg-green-700 focus:ring-green-500 text-sm text-center font-medium uppercase tracking-wider px-4 py-2 border border-transparent rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none no-underline">Subscribe</button>
</form>
</div>
How To Avoid Getting Electrocuted With LiveView AuthenticationThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2021/06/10/liveview-authentication2021-06-10T00:00:00Z2021-06-10T00:00:00Z<h3 id="have-you-heard-this-wise-old-story">Have you heard this wise, old story?</h3>
<p>A boilermaker is hired to fix a steamship boiler system. It’s a complex system of pipes and valves that would befuddle less knowledgeable engineers. Without a good grasp of how the entire system works, one would assume that a drastic overhaul is necessary.</p>
<p>But this boilermaker knows where to look and what to listen for. And after a single tap with a hammer to the right valve, the problem is fixed.</p>
<p>The person paying the bill is outraged: How could simply tapping a valve cost $1000?</p>
<p>To which the boilermaker responds: It’s $1 for tapping the valve, and $999 for knowing which valve to tap.</p>
<h3 id="just-this-morning-our-electrical-system-needed-a-tap">Just this morning, our electrical system needed a tap.</h3>
<p>For many months now we’ve been having an intermittent problem with our low voltage electrical panel. “Is the Internet down again?” has become a common refrain around the Studio. We roll our eyes and eventually one of us trundles over to the panel to troubleshoot.</p>
<p>Every fix I could think of seemed heavy-handed: a new breaker, spools of wire, and a lot of grunt work. So, hat in hand, I called over my electrician friend Hector to have a look. Fifteen minutes and 12 inches of wire later, the problem was fixed. Hector knows how our entire electrical system works, and therefore he knew where to “tap”. Quick, easy, and nobody got electrocuted!</p>
<h3 id="what-does-this-have-to-do-with-liveview-authentication">What does this have to do with LiveView authentication?</h3>
<p>Well, LiveView is a new way of doing things. When I first started using LiveView, it felt disorienting. It wasn’t immediately obvious how to do things in LiveView that I was used to doing in traditional web apps. And, without a guide like Hector to show me the ropes, I ended up over-complicating things. What should have taken minutes instead took hours. It was frustrating.</p>
<p>This was especially true when it came to LiveView authentication. Now I’m no stranger to authentication systems. I’ve built session-based auth systems from scratch and used generated systems. They all fundamentally work the same way: an HTTP session cookie is used to keep track of who’s currently logged in.</p>
<p>But it wasn’t obvious how to get LiveView to play well with a session-based authentication system. A LiveView communicates with the server over a websocket connection. And (here comes the rub) cookies can’t be set over a websocket.</p>
<p>So the solution must be complex (and potentially hazardous), right?</p>
<figure>
<img src="/images/blog/2021/06/torch-with-wires.jpg" width="400" />
</figure>
<h3 id="no-you-just-need-to-know-where-to-tap">No, you just need to know where to tap.</h3>
<p>And once you know where to tap, LiveView authentication is easy. It takes around 10 lines of neatly-formatted code. And it’s totally logical.</p>
<h3 id="really-just-10-lines-of-code">Really, just 10 lines of code?</h3>
<p>Yeah, that’s all it takes assuming you already have a session-based authentication system in place.</p>
<p>In our <a href="https://pragmaticstudio.com/courses/phoenix-liveview">LiveView Pro course</a>, we use the <a href="https://github.com/aaronrenner/phx_gen_auth">phx.gen.auth</a> library to generate a complete authentication system in one fell swoop. It’s the go-to authentication library for Phoenix and LiveView. A single command generates all the baseline code we need:</p>
<pre><code>mix phx.gen.auth Accounts User users
</code></pre>
<p>Here’s a high-level view of what that gives us right out of the box:</p>
<figure>
<img src="/images/blog/2021/06/phx-gen-auth.jpg" width="800" />
</figure>
<p>The entire system uses the core facets of Phoenix: database migrations, Ecto schemas, Phoenix context modules and controllers, REST routes, and the like.</p>
<p>One of the things we love about using phx.gen.auth is that it generates all the code inside your Phoenix application directory. No wires behind walls. No underground pipes. All the code is in plain sight and easy to access.</p>
<h3 id="and-well-walk-you-through-it">And we’ll walk you through it.</h3>
<p>In our <a href="https://pragmaticstudio.com/courses/phoenix-liveview">LiveView Pro course</a>, we look at the important parts of the code generated by phx.gen.auth so you understand how it all works. And you discover there is no magic.</p>
<p>It takes just 20 minutes, and by the end you’ll feel a lot more confident working with the code.</p>
<h3 id="aha-now-you-get-it">Aha, now you get it!</h3>
<h3 id="but-you-still-need-to-know-where-to-tap">But you still need to know where to tap.</h3>
<p>The code generated by phx.gen.auth knows who’s currently logged in because it has access to the session cookie. And, by way of a plug, the current user is automatically stashed in the Phoenix connection. But LiveViews aren’t automatically privy to what’s in the connection because LiveViews communicate on websockets.</p>
<p>Here’s where you need those 10 lines of code!</p>
<p>The second parameter passed to a LiveView’s mount callback is the session. And the session includes the current user’s token. So using the token and a function in the Accounts context module generated by phx.gen.auth, the LiveView can fetch the associated user from the database and store that user in the socket assigns:</p>
<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="k">def</span> <span class="n">mount</span><span class="p">(</span><span class="n">_params</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">socket</span><span class="p">)</span> <span class="k">do</span>
<span class="n">socket</span> <span class="o">=</span>
<span class="n">assign</span><span class="p">(</span>
<span class="n">socket</span><span class="p">,</span>
<span class="ss">:current_user</span><span class="p">,</span>
<span class="no">Accounts</span><span class="o">.</span><span class="n">get_user_by_session_token</span><span class="p">(</span><span class="n">session</span><span class="p">[</span><span class="s2">"user_token"</span><span class="p">])</span>
<span class="p">)</span>
<span class="p">{</span><span class="ss">:ok</span><span class="p">,</span> <span class="n">socket</span><span class="p">}</span>
</code></pre></div></div>
<p>And once the LiveView has access to the current user, you’re off to the races.</p>
<p>Well, kinda. But your database won’t be happy about it.</p>
<h3 id="theres-a-trick-you-wont-want-to-miss">There’s a trick you won’t want to miss.</h3>
<p>And judging by the number of questions on forums, many people don’t know this trick.</p>
<p>What happens on the server when a LiveView mounts and tries to fetch the current user? You’d expect a single database query, right? In fact, no less than 3 database queries are run! And the first time you bump into this, it’s baffling.</p>
<p>But it makes total sense when you break it down in terms of LiveView’s lifecycle. In the video, we go behind the scenes to see exactly what happens.</p>
<p>So we need to write custom code to reduce the number of queries, right?</p>
<p>Thankfully, no. In the same way that Hector knew how to solve our electrical problem with an elegant solution, LiveView has an elegant solution to lazily load the current user.</p>
<p>Simply by changing the code to use assign_new rather than assign tells LiveView to look for a current user in the connection before attempting to hit the database:</p>
<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="k">def</span> <span class="n">mount</span><span class="p">(</span><span class="n">_params</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">socket</span><span class="p">)</span> <span class="k">do</span>
<span class="n">socket</span> <span class="o">=</span>
<span class="n">assign_new</span><span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="ss">:current_user</span><span class="p">,</span> <span class="k">fn</span> <span class="o">-></span>
<span class="no">Accounts</span><span class="o">.</span><span class="n">get_user_by_session_token</span><span class="p">(</span><span class="n">session</span><span class="p">[</span><span class="s2">"user_token"</span><span class="p">])</span>
<span class="k">end</span><span class="p">)</span>
<span class="p">{</span><span class="ss">:ok</span><span class="p">,</span> <span class="n">socket</span><span class="p">}</span>
<span class="k">end</span>
</code></pre></div></div>
<p>If a current user doesn’t exist in the connection, the fallback function is invoked to fetch the user from the database.</p>
<p>And to avoid duplicating this code in every mount callback, we refactor it into a tidy function that can be called from any LiveView.</p>
<p>Again, it’s one of those things that’s easy once you know how to do it. And the <a href="https://pragmaticstudio.com/courses/phoenix-liveview">LiveView Pro course</a> includes an 11-minute video that walks you through it.</p>
<h3 id="time-for-your-top-secret-mission-">Time for your top-secret mission! 🕵️♀️</h3>
<p>To see a demo of what we build in the course, visit the top-secret LiveView. Only our clandestine team of agents get to see their mission, so you’ll be redirected to a login page.</p>
<p>But we let anyone join our secret intelligence service, so go ahead and click the “Register” link. You can create an account using any email address you please (we don’t send a confirmation email). And once your account is created, you’ll be automatically logged in and see a LiveView with your top-secret mission.</p>
<figure>
<img src="/images/blog/2021/06/top-secret-mission.png" width="400" />
</figure>
<h3 id="so-how-do-you-avoid-getting-electrocuted-with-liveview-authentication">So how do you avoid getting electrocuted with LiveView authentication?</h3>
<h3 id="you-join-us-in-the-liveview-pro-course">You join us in the LiveView Pro course!</h3>
<p>You’ll get 7 in-depth videos on authentication <strong>and</strong> 23 other videos on must-have LiveView topics. We’ve done all the research for you and distilled it in a concise set of videos paced for experienced developers.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/courses/liveview-pro-large.png" width="400" />
</a>
</figure>
LiveView Course Update: Modal ComponentsThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2021/04/13/liveview-course-modal-components2021-04-13T00:00:00Z2021-04-13T00:00:00Z<p>Hey Folks!</p>
<p>We’re excited to announce that our <a href="https://pragmaticstudio.com/phoenix-liveview">Phoenix LiveView course</a> is now content-complete and out of early access! 🙌</p>
<p>The best way to learn what Phoenix LiveView can do is to see it in action. So whether you’re just getting started with LiveView or going all-in, this course is for you!</p>
<p>We’ve spent hundreds of hours researching LiveView and building practical examples you can slip right into your application. Imagine all the time you’ll save and head banging you’ll avoid by taking the golden path. 💫 Trust us, our heads have small dents after working on this course for over a year. 🤕</p>
<h3 id="modal-component">Modal Component</h3>
<p>Today we released the final three videos in which we build a custom modal component from scratch. We think this is a great capstone example because it pulls together a bunch of techniques we learned earlier in the course: nested components, live navigation, key events, and more!</p>
<h3 id="getting-our-feet-wet">Getting Our Feet Wet</h3>
<p>We start off by building a basic modal component:</p>
<figure>
<img src="/images/blog/2021/04/sea-creatures-modal.png" width="400" />
</figure>
<p>The cool part is that modal visibility is driven off the URL using live actions, so you can bookmark modal pages and consistently traverse the browser’s history. And the modal component is truly reusable: you can use it to render any content.</p>
<h3 id="getting-practical">Getting Practical</h3>
<p>Then we use that component in a more realistic scenario to pop forms into a modal:</p>
<figure>
<img src="/images/blog/2021/04/new-server-modal.png" width="400" />
</figure>
<p>Finally, we bring things full circle by looking at the modal component that’s generated by the phx.gen.live generator. And (surprise!) there’s no longer any mystery to how it works!</p>
<figure>
<img src="/images/blog/2021/04/new-product-modal.png" width="400" />
</figure>
<p>With this example in hand, you’ll be well on your way to designing your own reusable components following LiveView best practices.</p>
<h3 id="so-how-do-you-get-these-new-videos">So how do you get these new videos?</h3>
<p>If you’ve purchased the Pro Package, you already have it! Just <a href="https://online.pragmaticstudio.com/signin">head over to the course</a> and you’ll find the videos in Module 35.</p>
<p>If you’ve been waiting for this course to be complete before snagging a copy, it’s now ready for you at a special launch price!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/courses/liveview-pro-large.png" width="400" />
</a>
</figure>
<p>We truly appreciate all the support you’ve given us as we’ve worked on this course. What started with a couple free videos around this time last year is now a full-blown course. 😅</p>
<p>We hope you all enjoy it!</p>
LiveView Course Update: File UploadsThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2021/03/30/liveview-course-file-uploads2021-03-30T00:00:00Z2021-03-30T00:00:00Z<p>Hey Folks!</p>
<p>File uploads are notoriously tricky to implement well, and yet it’s a common need. Roll your own? Nah, you’ve got better things to do than reinventing this wheel.</p>
<p>You’ll be happy to know that LiveView now supports file uploads right out of the box. It’s an impressive piece of engineering! And in typical LiveView fashion, you get a ton of functionality with just a few lines of code.</p>
<p>But as you’ve come to expect with us, we’re not satisfied to just slap in example code from the docs and call it a day. We want to understand what’s going on. So to really get a handle on file uploads, we built an application that lets you share photos of your desk.</p>
<figure>
<img src="/images/blog/2021/03/file-uploads.png" width="400" />
</figure>
<p>Pretty much what you’d expect, right? Drop some files into a form and (whoosh!) away they go. But there’s a lot more in play here than just a form that allows uploads.</p>
<p>To build this, we learn about:</p>
<ul>
<li>interactive file selection</li>
<li>auto-enforced constraints</li>
<li>validation error handling</li>
<li>client-side preview images</li>
<li>progress updates</li>
<li>drag and drop</li>
<li>consuming uploaded entries</li>
<li>uploading to your server</li>
<li>uploading to a cloud-storage service (Amazon S3)</li>
<li>real-time updates across browsers</li>
</ul>
<p>It’s 50 minutes chunked into 3 videos.</p>
<h3 id="how-do-i-get-the-new-module">How do I get the new module?</h3>
<p>If you’ve purchased the Pro Package, you already have it! You’ll find the <a href="https://online.pragmaticstudio.com/signin">3 new videos in the course</a> today.</p>
<p>If you haven’t yet snagged your copy of the Pro Package at the early access price, there’s still time. </p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/courses/liveview-pro-large.png" width="400" />
</a>
</figure>
<p>Up next, we’ll build a custom modal component…</p>
LiveView Course Update: Keyboard InteractivityThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2021/03/02/liveview-course-key-events2021-03-02T00:00:00Z2021-03-02T00:00:00Z<p>Happy Tuesday, Everyone!</p>
<p>We’ve got another new LiveView module ready for you today. This one’s all about key events. ⌨️</p>
<p>Now if you’re like us, your first thought might be that key events are mostly useful when building a game with LiveView. Arrow keys to move a character around. Spacebar to jump. And perhaps a CTRL+SHIFT+P combo to power up.</p>
<p>But key events are also super handy when building web apps. After all, who doesn’t prefer a keyboard shortcut over reaching for the mouse?</p>
<h3 id="want-to-see-a-juggling-act">Want to see a juggling act?</h3>
<p>As a fun example of how key events work, we built an image viewer for a juggling maestro:</p>
<figure>
<img src="/images/blog/2021/03/liveview-keyevents.png" width="400" />
</figure>
<p>The left and right arrow keys navigate to the previous and next images. Or you can type in an image number (0-18), hit the “Enter” key, and jump directly to that image. But the real fun begins when you hit the ‘k’ key to bring the lil’ juggler to life! It plays through the images at 4fps until you hit the ‘k’ key again to pause the action.</p>
<p>Not too shabby for around 80 lines of code! Thanks to LiveView’s first-rate support for key events, it’s really straightforward to build. In the 12-minute video you’ll learn everything you need to add keyboard interactivity to your own app. Plus we included two exercises where you’ll use key events in other scenarios, including live navigation.</p>
<h3 id="we-were-crazy-enough-to-draw-this">We were crazy enough to draw this!</h3>
<p>Our initial idea was to build a simple image viewer with next and previous hot keys. We didn’t know what we’d use for images. Worst case we’d include stock photos or selfies of Mike.</p>
<p>But then we thought: We can do better than that!</p>
<p>How about some hand-drawn cartoon artwork? And since this is LiveView and we’ve already learned how to send events on an interval, we could animate the cartoon to bring it to life. Kinda like a flipbook where you control the speed of the action with your thumb.</p>
<p>Well, as you might imagine, designing the cartoon turned into a fun project of its own! They say two heads are better than one, and it certainly took both of our brains to sort out all the arm and pin positions. Literally a juggling act of layers to create 19 frames. 🤯 🤯</p>
<p>We hope you enjoy it!</p>
<figure>
<img src="/images/blog/2021/03/liveview-drawing.jpeg" width="400" />
</figure>
<h3 id="new-video-playback-speed-controls">New Video Playback Speed Controls!</h3>
<p>We’ve heard from several of you who prefer to watch the videos at 1.5x or even 2x speed. And while Vimeo’s player has speed controls, it doesn’t remember the speed from video to video. So we fixed that!</p>
<p>You can now change the speed using Vimeo’s controls or the plus/minus buttons we added below the video, and it will remember your preferred setting. While we were at it, we also added handy 10s fast-forward and rewind buttons.</p>
<p>Give it a spin and let us know what you think!</p>
<figure>
<img src="/images/blog/2021/03/video-controls.png" width="400" />
</figure>
<h3 id="how-do-i-get-the-new-module">How do I get the new module?</h3>
<p>If you’ve purchased the Pro Package, you already have it! You’ll find the <a href="https://online.pragmaticstudio.com/signin">new video in the course</a> today.</p>
<p>If you haven’t yet snagged your copy of the Pro Package at the early access price, there’s still time. </p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/courses/liveview-pro-large.png" width="400" />
</a>
</figure>
<p>Up next, we’ll upload some of these juggling images into the cloud using LiveView’s built-in support for file uploads.</p>
It's Live: LiveView Pro Package Early Access!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2021/01/14/liveview-pro-early-access-opens2021-01-14T00:00:00Z2021-01-14T00:00:00Z<p>Howdy Friends,</p>
<p>It’s official: early access is now open for the Pro Package of our <a href="https://pragmaticstudio.com/courses/phoenix-liveview">Phoenix LiveView course</a>. So now you can get the course in two flavors…</p>
<h3 id="the-starter-package">The Starter Package</h3>
<p>Wondering what LiveView is all about? Want to cut through the hype and see real-life examples of what it can do?</p>
<p>The <a href="https://pragmaticstudio.com/courses/phoenix-liveview">Starter Package</a> is where you should, well, start! We’re offering it as a <strong>100% free community resource</strong> with no strings attached. It’s our gift to you. 🎁</p>
<p>You get 18 videos and 25 exercises showing you exactly how to start using LiveView to build rich, real-time user experiences with server-rendered HTML.</p>
<h3 id="the-pro-package">The Pro Package</h3>
<p>Curious what other problems LiveView can help you solve? Considering using it on your project?</p>
<p>The <a href="https://pragmaticstudio.com/courses/phoenix-liveview">Pro Package</a> picks up where the Starter Package leaves off and gives you more LiveView examples you can slip right into your application.</p>
<p>As of today, with early access you get <strong>18 more videos and 19 more exercises</strong>. And that’s just the beginning: <strong>more pro-level content is on the way!</strong></p>
<p>By purchasing this upgrade at the <strong>special early access price</strong> of $99, you can dive into the Pro Package today and get a steady diet of new sections until we’ve finished the course.</p>
<p>If just one video or example saves you an hour of time, it’s worth it! We’ve done all the work and research for you. 🤓</p>
<p>Also, by upgrading to the Pro Package you’ll allow us to continue offering the Starter Package as a free community resource. You’ll also help make this a sustainable endeavor for the two of us because, as we all know, LiveView will change. Your support will allow us to offer free updates to this course as necessary. 🙏</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/courses/liveview-pro-large.png" width="400" />
</a>
</figure>
<p><strong><a href="https://pragmaticstudio.com/courses/phoenix-liveview">Start the course</a> today to find out how LiveView brings the heat without any of the burn!</strong></p>
<p>Thanks for continuing to support our work. 💚</p>
LiveView Pro Course Update: TestingThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/12/08/liveview-course-update-testing2020-12-08T00:00:00Z2020-12-08T00:00:00Z<p>Hey Friends,</p>
<p>We’re back with another <a href="/phoenix-liveview">LiveView Pro course</a> update!</p>
<p>Hopefully you’ve had a chance to check out the <a href="https://pragmaticstudio.com/blog/2020/10/23/liveview-course-update-mapping">mapping</a>, <a href="https://pragmaticstudio.com/blog/2020/10/16/liveview-course-update-charting">charting</a>, and <a href="https://pragmaticstudio.com/blog/2020/11/06/liveview-course-update-authentication">authentication</a> updates.</p>
<p>And this week we’re wrapping up the outline for another section of the Pro course: ✅ testing.</p>
<p><strong>If you’ve done any browser-based testing, then you’re in for a real treat.</strong></p>
<p>Just as LiveView has changed how we create interactive user experiences, it has also changed how we test them. For the better!</p>
<p>Here are a few of our favorite things about testing LiveViews…</p>
<p><strong>1. No configuration necessary.</strong></p>
<p>None! You don’t have to monkey around with installing a web driver to drive all user interactions through a headless browser. Instead, your tests interact with LiveViews via process communication. No headless browser required.</p>
<p><strong>2. Tests are blazing fast!</strong></p>
<p>Without a headless browser gumming up the works, LiveView tests run orders of magnitude faster and are more reliable than typical browser-based tests. It makes sense: there’s no middle-man collecting a tax.</p>
<p>How fast? Well, we anticipate that the final code bundle for the Pro course will include 70+ LiveView tests. So far we’ve written 55 of them and they run in 0.7 seconds:</p>
<figure>
<a href="/phoenix-liveview" target="_blank">
<img src="/images/blog/2020/12/liveview-testing.png" width="800" />
</a>
</figure>
<p>Not too shabby for end-to-end tests. 😲</p>
<p><strong>3. They read like a good story.</strong></p>
<p>And we’re suckers for a good story.</p>
<p>For example, here’s a test for a volunteer checking out of an event:</p>
<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="n">view</span>
<span class="o">|></span> <span class="n">element</span><span class="p">(</span><span class="s2">"button"</span><span class="p">,</span> <span class="s2">"Check Out"</span><span class="p">)</span>
<span class="o">|></span> <span class="n">render_click</span><span class="p">()</span>
<span class="n">assert</span> <span class="n">has_element?</span><span class="p">(</span><span class="n">view</span><span class="p">,</span> <span class="s2">"button"</span><span class="p">,</span> <span class="s2">"Check In"</span><span class="p">)</span>
</code></pre></div></div>
<p>And here’s a test (with a custom helper) to make sure we find a suitable boat for our next water adventure:</p>
<div class="language-elixir highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="n">view</span>
<span class="o">|></span> <span class="n">form</span><span class="p">(</span><span class="s2">"#change-filter"</span><span class="p">,</span> <span class="p">%{</span><span class="ss">prices:</span> <span class="p">[</span><span class="s2">"$"</span><span class="p">]})</span>
<span class="o">|></span> <span class="n">render_change</span><span class="p">()</span>
<span class="n">assert</span> <span class="n">has_element?</span><span class="p">(</span><span class="n">view</span><span class="p">,</span> <span class="n">boat</span><span class="p">(</span><span class="n">budget_boat</span><span class="p">))</span>
<span class="n">refute</span> <span class="n">has_element?</span><span class="p">(</span><span class="n">view</span><span class="p">,</span> <span class="n">boat</span><span class="p">(</span><span class="n">expensive_boat</span><span class="p">))</span>
</code></pre></div></div>
<p>In a nutshell, with LiveView’s testing conveniences you can write browser-like tests from the comfort of Elixir without the overhead of a headless browser being in the mix. And that’s a huge win!</p>
<p><strong>But pros know that writing tests isn’t the ultimate goal.</strong></p>
<p>As with any browser-based testing library, it’s easy to get carried away with all the possibilities. We’ve all experienced test suites that include low-value, brittle tests that become a maintenance hassle. Someone changes the style of the page, and you end up fixing tests the rest of the afternoon. 😩</p>
<p>The pro’s goal is to build up a suite of high-value, effective tests.</p>
<p>So designing this section of the course took a bit longer than we expected (they all have!). We wanted to combine the right amount of “how to write tests” with “what to test” to set you on the right path.</p>
<p>To help us do that, we reached out to <a href="https://twitter.com/germsvel" target="_blank">German Velasco</a> who’s working on an <a href="https://www.testingliveview.com" target="_blank">entire course</a> dedicated to testing LiveView effectively. He graciously reviewed all our tests and lended us his valuable feedback and insights.</p>
<p>We think you’ll love the result!</p>
<p><strong>So buckle up to binge watch hours and hours of testing!</strong></p>
<p>Just kidding. 🤪</p>
<p>Writing 50+ tests from scratch would test your patience… and ours! You’d likely score a nap though. 😴</p>
<p>So in the videos we’ll strategically write tests for some of the LiveViews we’ve built so far, focusing on tests that teach us something new, including:</p>
<ul>
<li>
<p>External user events</p>
</li>
<li>
<p>Internal events</p>
</li>
<li>
<p>Live Navigation</p>
</li>
<li>
<p>Components</p>
</li>
<li>
<p>Pub-Sub</p>
</li>
<li>
<p>JS Hooks</p>
</li>
<li>
<p>Custom Helpers</p>
</li>
</ul>
<p>Then in the exercises you can apply what you learned toward testing features we didn’t test together. And the final code bundle will include tests for <strong>all</strong> the LiveViews as a reference.</p>
<p><strong>Want to guess last week’s FAQ?</strong></p>
<p>If you guessed “When can I get the Pro course?”, then you win the big prize! 🏆</p>
<p>Seriously, we very much appreciate your interest and patience. Good things take time. 😀</p>
<p>In next week’s update we hope to have more details about early access. So stay tuned!</p>
LiveView Pro Course Update: AuthenticationThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/11/06/liveview-course-update-authentication2020-11-06T00:00:00Z2020-11-06T00:00:00Z<p>Greetings Friends,</p>
<p>We’re back with another <a href="/phoenix-liveview">LiveView Pro course</a> update!</p>
<p>Hopefully you’ve had a chance to check out the <a href="https://pragmaticstudio.com/blog/2020/10/23/liveview-course-update-mapping">mapping</a> and <a href="https://pragmaticstudio.com/blog/2020/10/16/liveview-course-update-charting">charting</a> examples. This week we have an update on the next example that’s in the works.</p>
<p><strong>But first, let’s roll back the clock two decades…</strong></p>
<p>In the days before you could play any song you wanted at any time, you would call in to a radio station and request a song. It sounds so quaint now, but it was super cool back then. 😎</p>
<p>You’d dial the station’s telephone number (on a landline, of course) and request a song you wanted to hear. “Can you please play Who Are You by The Who?” Then you’d wait…</p>
<p>And if you were really lucky, within the next 30 minutes you’d hear the station’s D.J. announce “This one’s for Mike…” right before playing your favorite jam. 🎶</p>
<p>Wow, that made you feel special! They actually played <em>your</em> song for <em>you!</em></p>
<p><strong>So what’s all this got to do with our next LiveView example?</strong></p>
<p>Well, you’ve lit up our request line wanting to hear about LiveView authentication. It’s literally everybody’s most desired song right now. So if you requested authentication, this one’s for you! 👍</p>
<p>And we totally get why it’s a popular request. Authentication isn’t in the nice-to-have column of your project requirements. It’s a <em>must-have requirement</em> for any application that has members-only features.</p>
<p>Sooner or later, you’re going to need a secure authentication system that works seamlessly with LiveView.</p>
<p><strong>Here’s a top-secret example we’ve been working on.</strong></p>
<p>🕵️♀️ Suppose we need a secure way for a clandestine team of agents to get their super-secret missions.</p>
<p>First, to access the LiveView page that displays your next mission, you have to be logged in:</p>
<figure>
<img src="/images/blog/2020/11/login.png" width="471" />
</figure>
<p>Don’t have an account? No problem. You can create one. Yep, anyone can join our secret intelligence service:</p>
<figure>
<img src="/images/blog/2020/11/register.png" width="471" />
</figure>
<p>Then once you have an account and you’re logged in, you can access the LiveView to get your next super-secret mission.</p>
<figure>
<img src="/images/blog/2020/11/topsecret.png" width="500" />
</figure>
<p><strong>There’s a lot of moving parts behind the scenes to make this work.</strong></p>
<p>That’s why it’s called an authentication <em>system</em>. 😉 And users will expect some standard features, including:</p>
<ul>
<li>
<p>User accounts</p>
</li>
<li>
<p>User registration with email confirmation</p>
</li>
<li>
<p>Session-based login/logout</p>
</li>
<li>
<p>Remember me cookies</p>
</li>
<li>
<p>Resetting a forgotten password</p>
</li>
<li>
<p>Safely changing account settings</p>
</li>
</ul>
<p>You know the drill.</p>
<p><strong>Also, did we mention it must be secure?</strong></p>
<p>Our legal team reminded us that we need to remind you: The authentication system must be secure!</p>
<p>Basically that means you have to 1) think like a hacker and 2) set up defenses to block all their potential malicious moves. That generally involves techniques such as:</p>
<ul>
<li>
<p>Generating, verifying, and expiring time-based tokens</p>
</li>
<li>
<p>Avoiding session fixation and timing attacks</p>
</li>
<li>
<p>Properly hashing and storing passwords</p>
</li>
<li>
<p>Disconnecting websockets on log out</p>
</li>
</ul>
<p>All the reasons you got into programming in the first place, right?</p>
<p><strong>Oh, and it must be tested, too.</strong></p>
<p>Every scenario. Every corner case. Every line of code. Because when it comes to authentication, everything is on the line. One small regression could result in sensitive data being compromised. 😱</p>
<p>It’s no surprise then that the automated tests themselves are the biggest chunk of code in a secure authentication system.</p>
<p><strong>Holy moly, that’s totally overwhelming!</strong></p>
<p>Good thing there’s a library to rescue us from this daunting mission. By using the <a href="https://github.com/aaronrenner/phx_gen_auth">phx.gen.auth</a> library, we can generate a complete authentication system that follows all the best practices.</p>
<p>Now, we tend to be skeptical when it comes to generated code, but this is different. The code generated by the <code>phx.gen.auth</code> library was <a href="https://dashbit.co/blog/a-new-authentication-solution-for-phoenix">written by José Valim</a>. He’s the the creator of Elixir and co-creator of Phoenix and LiveView. Moreover, he has a ton of experience designing and implementing authentication systems. There’s literally nobody on the planet more qualified to write the code generated by this library. For that reason, <code>phx.gen.auth</code> is the go-to authentication library for Phoenix and LiveView.</p>
<p>There’s another reason we love using <code>phx.gen.auth</code>: all the code is generated in plain sight inside your Phoenix application directory. Nothing is shrouded behind a framework. That makes it easy to walk through the code and see how it all works. 👀</p>
<p>So that’s exactly what we’re going to do!</p>
<p><strong>We’ll tackle this important topic in two parts.</strong></p>
<p>First, we’ll walk through the relevant bits of the generated code so it doesn’t feel magical. To keep a reasonable pace, we’ll assume you’re familiar with the concepts of session-based authentication.</p>
<p>You’ll be pleasantly surprised by the neatness and structure of the generated code. <em>It’s a master class in doing things the Elixir and Phoenix way.</em></p>
<p>Then we’ll explore how to ensure that only authenticated users can access a LiveView. Doing that takes very little code, but the story unfolds with a bit of a twist.</p>
<p>You see it coming when you recall that a LiveView’s mount callback is invoked twice: once for the initial HTTP request and again when the client has connected to the websocket. Therefore, user authentication steps must be performed in both the disconnected and connected states.</p>
<p>And that raises questions such as:</p>
<ul>
<li>
<p>How does a LiveView access session data in both states?</p>
</li>
<li>
<p>How do you reduce authentication-related database queries?</p>
</li>
<li>
<p>How can you share connection assigns in the disconnected state?</p>
</li>
<li>
<p>How can you use a LiveView for a feature that sets browser cookies given that cookies can’t be set over a websocket connection?</p>
</li>
</ul>
<p>🤩 There’s a lot of ground to cover! But after a few iterations on the script, we think we’ve cut a clear learning path. Right now we’re estimating 3 videos and at least 2 animations.</p>
<p><strong>But what if you’re using another authentication system?</strong></p>
<p>Thankfully, all the techniques are the same! So regardless of which system you use, you’ll know how to use it to authenticate LiveViews after watching these videos.</p>
<p><strong>So that’s the plan. Whaddaya think?</strong></p>
<p>We’d love to know your thoughts and questions.</p>
<p>Once again, thanks for your interest in the <a href="/phoenix-liveview">LiveView Pro course</a>! 😊</p>
LiveView Pro Course Update: Mapping DemoThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/10/23/liveview-course-update-mapping2020-10-23T00:00:00Z2020-10-23T00:00:00Z<p>Howdy again, friends!</p>
<p>First, many thanks for all your positive responses about the <a href="https://pragmaticstudio.com/blog/2020/10/16/liveview-course-update-charting">charting demo</a> we sent out last week. We’ve made a couple small tweaks based on your suggestions, but otherwise it sounds like we’re on the right track. It’s encouraging to hear that this example will be useful to those of you looking to do real-time charting with a JS library. 📊 📉</p>
<p><strong>Continuing with JS interop, let’s do some mapping!</strong></p>
<p>🌎 No surprise, charting and mapping examples were the two big requests when it came to JS interop.</p>
<p>So we’ve been working hard on a mapping example that we think really showcases some unique JS interop features of LiveView. It renders a map with markers for incidents that need attention in your area: 🔥 BBQ fire , 🐻 Bear in the trash, 🙀 Cat stuck in a tree , and so on.</p>
<p>Of course time is of the essence when it comes to emergencies, so everything is updated in near real-time. Seeing up-to-date reports of what’s going on nearby gives everyone an opportunity to pitch in and help!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/10/mapping-demo.png" width="500" />
</a>
</figure>
<p><strong>Two-way, real-time interaction.</strong></p>
<p>This example demonstrates an interesting back and forth between the LiveView and the map:</p>
<ul>
<li>
<p>Selecting an incident from the list centers that incident’s marker on the map and shows a popup with a description.</p>
</li>
<li>
<p>Clicking a marker on the map highlights the corresponding incident in the list, scrolling the list if necessary to bring the selected incident into view.</p>
</li>
<li>
<p>Reporting an incident broadcasts a message which adds the new incident to the list and drops a marker on the map. Go ahead and hit that “Report Incident” button (we know you want to!) and you’ll see a random dog or cat in trouble.</p>
</li>
<li>
<p>And if you open two browser windows, you’ll see real-time updates across sessions so everyone’s in the loop!</p>
</li>
</ul>
<p>To get this two-way interaction, we’re pushing events both ways across the websocket: from the LiveView running on the server to the JS hook running in the browser, and vice versa. We also used a new LiveView feature to reply to a pushed event, which turns out to be super handy. 👍</p>
<p><strong>The specific JS mapping library doesn’t really matter.</strong></p>
<p>We’re using the <a href="https://leafletjs.com">leaflet</a> library since many of you recommended it. However, we’ve encapsulated all the leaflet-specific code in a JS class with a simple API. It lets you create a map, add a marker to the map, and pan the map to center a marker.</p>
<p>Any mapping library worth its salt will let you do those three basic things. So you could easily adapt this example to use <a href="https://openlayers.org">OpenLayers</a>, <a href="https://developers.google.com/maps/documentation/javascript/overview">Google Maps</a>, or your favorite mapping library.</p>
<p>All the good stuff as far as we’re concerned happens in the JS hook we write from scratch. It’s a thin layer that effectively connects the LiveView and whatever JS mapping library you use.</p>
<p><strong>Now here’s a little secret.</strong></p>
<p>We could easily branch out from here into all sorts of examples that demonstrate JS interop. And indeed we have a few choice examples we aim to explore later in the Pro course. (Alpine, anyone?)</p>
<p>But based on what you’ll learn in the charting and mapping examples, the world (as they say) will be your oyster. 🦪 😋 Once you know about pushing interaction events back and forth between a LiveView and a JS hook, you can use them to build pretty much whatever you want.</p>
<p>So even if you don’t plan to do any charting or mapping, we think you’ll get a lot of value out of these two examples. Think of them as meta-skills that have a longer shelf life than just knowing how to make a chart or map. 😀</p>
<p><strong>Let us know what you think!</strong></p>
<ul>
<li>
<p>Does this example align with what you’re wanting to learn and do?</p>
</li>
<li>
<p>Any changes that would make this example more useful to you?</p>
</li>
<li>
<p>Did we overlook anything that would be generally applicable?</p>
</li>
</ul>
<p>Thanks again for your interest in the Pro course! 🤟</p>
LiveView Pro Course Update: Charting DemoThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/10/16/liveview-course-update-charting2020-10-16T00:00:00Z2020-10-16T00:00:00Z<p>Hey friends, we’re baaack!</p>
<p>Hope you’re continuing to get a lot of value from the <a href="https://pragmaticstudio.com/courses/phoenix-liveview">free LiveView course</a>.</p>
<p>Last month we <a href="https://pragmaticstudio.com/blog/2020/09/10/liveview-course-update-14">announced</a> that we were beginning work on a LiveView Pro course as an extension of the free Starter course. We were excited about it, but didn’t know what you’d think of the idea. So we asked…</p>
<p>And WOW, we were blown away by your enthusiasm for the Pro course! Many thanks for all the encouraging 👍, 🥳, and 💯 responses. We’re sincerely humbled and grateful for your continued support.</p>
<p><strong>So it’s game on!</strong></p>
<p>We’ve taken all your suggestions, reprioritized a few topics, and have been working diligently on the course. OK, we might have played hooky a few days to go fishing and enjoy the beautiful fall weather. Nevertheless, we’re making good progress and have some examples we’re ready to start showing.</p>
<p>Here’s where we need your help. As the course progresses, we’ll send updates with behind-the-scenes looks at what we’re working on. It would be tremendously helpful if you’d let us know if what you see is aligned with what you need (or not). The more input we get from you, the better the course will be. Because, after all, we’re making the course for you!</p>
<p><strong>Without further ado, here’s the first behind-the-scenes peek.</strong></p>
<p>Many of you asked for an example of a LiveView that charts data using a JavaScript library such as <a href="https://www.chartjs.org">Chart.js</a>.</p>
<p>So we’ve been working on a time-series chart that automatically updates every hour. Just to make it interesting, we’re charting a person’s blood sugar level. Don’t worry, you don’t have to hook anything up to a human body to make it work. 😉</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/10/charting-demo.png" width="500" />
</a>
</figure>
<p><strong>It’s a rolling 12-hour time-series chart.</strong></p>
<p>It starts out with an initial set of data points for the previous 4 hours. But instead of having to wait an hour to see the next data point appear, through the magic of programming we sped up time. So every second a new data point is automatically added. At any time you can also manually check the current blood sugar level which adds a new data point to the chart.</p>
<p>And yes, this person’s blood sugar is all over the place! It wouldn’t vary that wildly over a 12-hour period. But using a random value within a range makes for a more interesting chart.</p>
<p><strong>The domain is irrelevant.</strong></p>
<p>While this example is for medical data, very little of the code is specific to that domain. Simply by changing the labels and x-y values you could chart performance metrics, polling data, or ice cream sales. Indeed, the type of data and where it comes from is irrelevant.</p>
<p><strong>What is relevant is how the data gets passed from the LiveView to the JavaScript charting library.</strong></p>
<p>And that’s the sole focus of this example: the LiveView-JavaScript touchpoints. The techniques are the same regardless of the data or even which JS charting library you use.</p>
<p><strong>So how does it work?</strong></p>
<p>Given what you’ve already learned in the infinite scrolling example, you probably guessed that charting involves using a JavaScript hook. And you’re absolutely right! The difference with charting is that the data is flowing the other way.</p>
<p>In the infinite scrolling example, the JavaScript pushed an event to the LiveView running on the server to tell it to load more results. Charting is the other way around. The LiveView needs to push an event to the JavaScript so that a new data point is added to the chart. The LiveView also needs to pass the initial set of data points to the graph when it’s hooked in.</p>
<p>So this example teaches us something new, building on what we already know.</p>
<p><strong>Now it’s your turn!</strong></p>
<ul>
<li>
<p>Is this the kind of thing you’re wanting to do?</p>
</li>
<li>
<p>Any changes that would make this example more useful?</p>
</li>
<li>
<p>Did we overlook anything that would be generally applicable?</p>
</li>
</ul>
<p>Thanks again for your interest in the Pro course! 🤟</p>
LiveView Course Update: Example #15 and What's Up NextThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/09/10/liveview-course-update-142020-09-10T00:00:00Z2020-09-10T00:00:00Z<p>😯 We’ve arrived this week at our 15th LiveView example! Four months ago we opened early access to our free <a href="/phoenix-liveview">Phoenix LiveView course</a> with 7 examples and exercises.</p>
<p>Since then thousands of you picked up the course and have been sending us ideas and questions about using LiveView in various scenarios. Over the summer we created and released 7 more examples. So, what’s next?</p>
<p><strong>First up, we’re now at groovy example #15!</strong></p>
<p>This example takes on a topic that we discovered is actually quite impossible to fully cover in a single short video: live components.</p>
<p>If you’ve used something like React or Vue, then you’re familiar with splitting your UI into reusable, easy-to-maintain components. No surprise, you can do the same thing with LiveView!</p>
<p>For this week’s example (and giving one last nod to summer), we look at calculating the number of pounds of sand you’d need to build the sandbox of your dreams. 🏖</p>
<p>To pull this off, we use two different flavors of LiveComponents – stateless and stateful – and learn one way to communicate between them.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/09/sandbox.png" width="436" />
</a>
</figure>
<p>This example sets a good foundation on what could otherwise be sandy soil. It introduces us to the core facets of components, how stateless and stateful components differ, and how data flows down and events flow up.</p>
<p>If you already own this course, you’ll find this new LiveView example in your account today.</p>
<p>Now, there’s obviously more to consider when designing components. And in general, there’s a LOT more you can do with LiveView. Indeed, we have quite a few examples already sketched out that we’d love to finish and share with you.</p>
<p><strong>Which leaves us in a bit of a conundrum…</strong></p>
<p>If you’ve been with us since April, then you know our original plan was to put out roughly 13 videos of common UI challenges that LiveView neatly solves.</p>
<p>Once those were rolled out, we planned to turn our attention back to developing a different course – a course we’d charge for. After all, the electric company won’t keep our power on despite us having a LightLive controller. And a LicenseLive form won’t pay our health insurance bill without a “Buy” button. 😜</p>
<p><strong>So… what to do?</strong></p>
<p>More LiveView?</p>
<p>Another topic?</p>
<p>Free course?</p>
<p>Paid course?</p>
<p>Open a bait and tackle shop?</p>
<p>🤔</p>
<p>These are always difficult decisions for us because there’s only two of us. Whatever we decide becomes the primary focus for both of us for the next several months. So it’s always a bit of a gamble when choosing what to do next.</p>
<p>But based on the tremendous amount of positive feedback and ideas you’ve shared, we’ve decided to keep making fun and practical LiveView examples!</p>
<p>The first set of examples will remain available for free as the <strong>LiveView Starter Course</strong>. And (drum roll, please) we’ve begun creating new examples and exercises for the <strong>LiveView Pro Course</strong>. 🎉</p>
<p>Just a few of the areas we’ve already started to explore include:</p>
<ul>
<li>
<p>More on <strong>LiveComponents</strong> such as extracting reusable components, how they fit into a more complex app, and parent-child communication using Phoenix PubSub</p>
</li>
<li>
<p>More ways to <strong>interop with JavaScript</strong> including charts and maps</p>
</li>
<li>
<p><strong>Authentication</strong> since this topic turned out to be more involved than we originally anticipated 😆</p>
</li>
<li>
<p><strong>Testing</strong> because many of you asked for it and LiveView has such a great testing story</p>
</li>
<li>
<p>Designing a <strong>custom modal component</strong> for dialogs and notifications</p>
</li>
<li>
<p><strong>Live progress updates</strong> for background jobs</p>
</li>
<li>
<p><strong>File uploads</strong> which, according to Chris McCord, are coming soon to LiveView</p>
</li>
</ul>
<p>This will be a paid course, and we fully intend to give you more than your money’s worth. <strong>By purchasing the Pro version later this year, you’ll allow us to continue updating and offering the Starter version as a free community resource. And you’ll also help make this a sustainable endeavor for the two of us.</strong></p>
<p>So that’s our plan for the next few months.</p>
<p><strong>We would love to hear what you think!</strong> And if you have specific things (big or small) you’d like to see built with LiveView, we’re still taking requests.</p>
<p>Thanks for being with us on this ride!</p>
LiveView Course Update #13: JavaScript InteropThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/08/25/liveview-course-update-132020-08-25T00:00:00Z2020-08-25T00:00:00Z<p>We’re in the dog days of summer here in the US. 🐶 Which basically means when we’re not thinking about, researching, or coding up LiveViews, we’re scurrying for a cool lake or shady hammock to flop in.</p>
<h3 id="updates-for-phoenix-154-liveview-0144-and-tailwind-17">Updates for Phoenix 1.5.4, LiveView 0.14.4, and Tailwind 1.7</h3>
<p>We’ve been tracking the changes in Phoenix, LiveView, and Tailwind CSS. The latest minor versions include bug fixes and enhancements. So this week we updated the course code bundle for our <a href="/phoenix-liveview">Phoenix LiveView course</a> to use Phoenix 1.5.4 (from 1.5.3), LiveView 0.14.4 (from 0.13.3) and Tailwind 1.7 (from 1.2).</p>
<p>Now don’t worry: these updates didn’t impact any of the code we wrote in the videos or any of the exercises. All of that code is still 100% accurate with no changes. 👍 So why did we update the code? Well, mainly just to keep everything up-to-date and so we can take advantage of the new enhancements in future videos.</p>
<p>If you’ve already downloaded the code bundle and want to update a specific branch (totally optional), you can pull the changes from our remote repo. For example, to get the code for today’s new video on JS interop, you’ll need to run:</p>
<pre><code> git checkout 14-infinite-scroll-begin
git pull origin 14-infinite-scroll-begin
</code></pre>
<p>The changes include updated mix.exs and assets/package.json files with updated dependency versions. Then, to fetch the new versions, run:</p>
<pre><code> mix deps.get
npm install --prefix assets
</code></pre>
<p>Or, if you don’t mind having your database reset, you can simply run:</p>
<pre><code> mix setup
</code></pre>
<h3 id="liveview-example-14-infinite-scrolling-using-javascript">LiveView Example #14: Infinite Scrolling using JavaScript</h3>
<p>In this week’s video we invite some JavaScript to the LiveView party. 🎉</p>
<p>Based on your suggestions and questions about integrating JavaScript into LiveViews, we researched a bunch of ideas. There are tons of fun things we could do with JS and LiveViews, but we were specifically looking for an initial example that was both interesting and relatively simple. When things get too complicated too quickly, it’s easy to miss the first principles.</p>
<p>So here’s where we landed: We came up with a yummy example that uses a small bit of JavaScript to let you infinitely scroll through a long list of pizza orders. Every time you scroll to the bottom of the page, a new batch of orders is automatically fetched from the database. Buttery-smooth scrolling!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/08/pizza-timeline.png" width="436" />
</a>
</figure>
<p>It’s a great first example of how to get JavaScript running in the browser to communicate with a LiveView running on the server. And you can try your hand at JS interop in the exercises where you’ll use JS libraries pulled straight down from npm.</p>
<p>If you already own this course, you’ll find this new video with exercises in your account today.</p>
<h3 id="thats-it-isnt-there-more">That’s it? Isn’t there more?</h3>
<p>Indeed! There is much more we could do with JavaScript and LiveViews. We could, for example, use third-party JavaScript libraries to do charting, mapping, and all sorts of cool stuff. This 16-minute video is the jumping off point for many possibilities.</p>
<p>So it might surprise you that next video is going to be about LiveComponents. 😳 That probably wasn’t exactly what you were expecting to hear, was it?</p>
<p>You want more examples using JavaScript!</p>
<p>And after the introduction to components in the next video, you’re going to want more examples of LiveComponents, too.</p>
<p>So yes, there is SO MUCH MORE!</p>
<p>In our next update, we’ll release our 15th LiveView example in the free course and reveal where we’re going from here. 🚀</p>
LiveView Course Update #12: Real-Time UpdatesThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/08/04/liveview-course-update-122020-08-04T00:00:00Z2020-08-04T00:00:00Z<p>When we roll out an early access course video by video, like we’ve been doing with our <a href="/phoenix-liveview">Phoenix LiveView course</a>, we usually get two responses:</p>
<p>😄 “Hooray, another video this week! This incremental rollout is the perfect way for me to keep up without feeling overwhelmed by hours of content.”</p>
<p>or</p>
<p>🙄 “Ugh, stop with the slow dribble and cliffhangers! Tell me when you’re done and then I’ll go through the course top to bottom.”</p>
<p>For those of you in the second category, we’ve got bad news: we’re not done yet!</p>
<p>And for those of you in the first category, we’ve got great news: we have a new video for you this week!</p>
<h3 id="example-13-real-time-updates">Example #13: Real-Time Updates</h3>
<p>The last video ended with a bit of a dilemma. Using the app, volunteers can now check in and check out. Yay! But a change in status doesn’t automatically show up across browser sessions. If you want to get the latest updates, you have to reload the page. 😝</p>
<p>We need a way to send updates between LiveViews so that everything stays in sync. We need real-time updates!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/08/real-time-updates.png" width="436" />
</a>
</figure>
<p>Thankfully we don’t have to look far and wide for a solution. Phoenix PubSub gives us a handy API for subscribing to topics of interest and broadcasting messages to subscribers in a snappy, distributed way.</p>
<p>If you already own this course, you’ll find this new example along with the capstone exercise in your account today. If you haven’t snagged a copy of this FREE course, there’s still time!</p>
<h3 id="liveview-for-svg-updates-and-livepatch">LiveView for SVG Updates And live_patch</h3>
<p>If you’ve hung around the Studio at all, you know that at the end of all our courses we say the exact same thing: “Now it’s your turn to go build something with (whatever you just learned).”</p>
<p>It doesn’t matter if it’s a hobby project, a feature in your company’s app, or a contribution to an open source project. Just go build something!</p>
<p>And that’s what we like so much about <a href="https://twitter.com/mudphone">Kyle Oba’s</a> LiveView project. When he heard that a website for creating star polygons recently went offline, he thought, “I wonder if I can recreate it?” 🤔</p>
<p>The math geeks and artists among us can appreciate his curiosity. Star polygons are cool and beautiful.</p>
<p>But Kyle had an interesting challenge. He had never actually seen the original site for himself, but that didn’t deter him. He says, “Based on a description of the site, some printed math handouts, and a liberal use of Wikipedia, I reconstructed the main parts of the tool.”</p>
<p>The result is a lot of <a href="https://www.pasdechocolat.com/starpolygon">fun to play with</a>. You can make your own regular or not so regular (who knew?!) star polygons:</p>
<figure>
<a href="https://www.pasdechocolat.com/starpolygon">
<img src="/images/blog/2020/08/polygon.png" width="542" />
</a>
</figure>
<p>Kyle uses LiveView to update the SVG frontend and other text values. He also uses live_patch to put parameters for vertices and density in the URL. That way anyone using the app can share specific star patterns via bookmarkable URLs.</p>
<blockquote>
"I used your course to polish this site up quite a bit, and I’m hoping to keep at it as the course progresses." - Kyle Oba
</blockquote>
<p>We can’t wait to see how you continue to refine it, Kyle! We give it 5 out of 5 polygons ⭐️⭐️⭐️⭐️⭐️!</p>
LiveView Course Update #11: Toggle StateThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/07/23/liveview-course-update-112020-07-23T00:00:00Z2020-07-23T00:00:00Z<p>Thanks for your continued interest in our <a href="/phoenix-liveview">Phoenix LiveView course</a>!</p>
<p>One of the most rewarding parts of making this course has been hearing from you! Since our initial rollout, many of you have emailed asking:</p>
<ul>
<li>How would I use LiveView to…?</li>
<li>What’s the best way to implement LiveView in a scenario like…?</li>
<li>You’re going to have a video on XYZ with LiveView, right? 😉</li>
</ul>
<p>In large part due to your suggestions, our list of ideas and examples grows almost daily!</p>
<p>Others of you have emailed or tweeted us about what you’ve learned and how you’re now rolling LiveView into production apps.</p>
<blockquote>
"I've been writing Elixir for a few years and had a hard time wrapping my mind around the LiveView programming model. Your course gave me the know-how and confidence to get a couple of LiveViews configured and running in our production Phoenix app!" — Matthew Lehner
</blockquote>
<p>That’s awesome! If you have an external-facing app that uses a LiveView feature, we’d love to hear about it. Perhaps we can even show it off for you in our next update. Together we can inspire each other with new ideas.💡</p>
<h3 id="example-12-toggling-state">Example #12: Toggling State</h3>
<p>On or off? Pending or completed? Draft or published? Your UI often needs a quick and easy way to toggle a bit of state.</p>
<p>In our volunteers example, you can currently check in but you can’t check out. It’s a bit like the Eagles’ song “<a href="https://www.youtube.com/watch?v=vcmjDPDOk7c">Hotel California</a>” 😳</p>
<blockquote>
Last thing I remember<br />
I was running for the door<br />
I had to find the passage back<br />
To the place I was before<br />
"Relax," said the night man<br />
"We are programmed to receive<br />
You can check out any time you like<br />
But you can never leave"
</blockquote>
<p>In this week’s new video, we let volunteers toggle their state between checked in and checked out, and then actually leave!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/07/toggle-state.png" width="600" />
</a>
</figure>
<p>If you’ve already picked up a copy of the course, you’ll find this new video along with a new exercise in your account today. And we’re so on the ball this week that the video already has subtitles! 😁</p>
<p>In the next video we’ll publish real-time updates across multiple browser sessions. Stay tuned!</p>
LiveView Course Update #10: Live ValidationThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/07/17/liveview-course-update-102020-07-17T00:00:00Z2020-07-17T00:00:00Z<p>As we left things in the previous video of our <a href="/phoenix-liveview">Phoenix LiveView course</a>, we have a form in place for checking in volunteers to our event. That form creates volunteers in our database and then updates the list of volunteers all without a full page reload. Perfect, except…</p>
<p>Even though we’re validating the volunteer’s data, the actual validation isn’t happening until the “Check In” button is clicked. That’s kinda a bummer. 😟</p>
<p>So this week we look at how easy it is to display real-time validation errors:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/07/live-validation.png" width="600" />
</a>
</figure>
<p>If you’ve already picked up a copy of the course, you’ll find this new video along with a new exercise in your account today.</p>
<p>Enjoy!</p>
LiveView Course Update #9: Form CreateThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/07/09/liveview-course-update-92020-07-09T00:00:00Z2020-07-09T00:00:00Z<p>Happy summertime to you! 😎</p>
<p>We’re back with another update on our <a href="/phoenix-liveview">Phoenix LiveView course</a>. In the next four videos, we’re going to unpack:</p>
<ul>
<li>Form Create</li>
<li>Live Validations</li>
<li>Toggling State</li>
<li>Real-Time Updates</li>
</ul>
<p>To demonstrate these common UI scenarios, imagine you’re an event coordinator in a post-pandemic world where we can socially gather again. Your event requires a bunch of volunteers and so you need a way to keep track of everyone. Specifically, you want to:</p>
<ul>
<li>collect each person’s name and phone number in a form</li>
<li>validate each name and number</li>
<li>add each volunteer to a database</li>
<li>display a list all the volunteers and their current status</li>
<li>toggle a volunteer’s state between checked in/out</li>
<li>keep everything updated in real-time</li>
</ul>
<p>Oh yeah, and you want to do it all without full page reloads.</p>
<p>No sweat! 😅 LiveView can handle all this with only ~100 lines of code. We’ll show you how in the next four videos!</p>
<h3 id="live-create-with-ecto-changesets">Live Create With Ecto Changesets</h3>
<p>In this week’s 22-minute video we start off the app by using Ecto and changesets to dynamically create volunteers and check in each one to the event, like so:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/07/form-create.png" width="600" />
</a>
</figure>
<p>If you’re unfamiliar with Ecto changesets, we recommend checking out “Module 17: A Peek At Phoenix” in our <a href="/courses/elixir">Elixir & OTP course</a>.</p>
<h3 id="live-create-servers">Live Create Servers</h3>
<p>Some of you told us that the exercises for sorting and pagination were too copy/paste-y. Well, we can’t have that! This week’s example is intended to give you a little challenge.</p>
<p>Remember the live navigation example that listed servers? Wouldn’t it be convenient if we had a way to add servers to that list? 😉 To do so, you’ll need to create a live form and build on what you know about live navigation.</p>
<p>Here’s the goal:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/07/server-create.png" width="600" />
</a>
</figure>
<p>Hopefully this exercise keeps your fingers away from those tempting copy, paste, find, and replace keys. 🙈 If you’ve already picked up a copy of the course, you’ll find this new video and exercise in your account today.</p>
<p>Enjoy!</p>
Don't Make The Same Mistake Mike Did 😩The Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/06/30/dont-make-the-same-mistake-mike-did2020-06-30T00:00:00Z2020-06-30T00:00:00Z<p>Howdy!</p>
<p>Mike here with a small confession to make. I failed my first semester of college Calculus. It was devastating!</p>
<p>I went from being a straight-A student in high school to a college flunky. As the first person in my family to go to college, my parents went from being over-the-moon proud to what-in-the-world worried. 😬</p>
<p>You have to understand, Calculus wasn’t an elective course for me. It was a requirement for a Computer Science degree. And Calc I was only the beginning. Calc II and other advanced math courses were in my future.</p>
<p>So what went wrong?
Did I not try hard enough? 🤓
Did I party too much? 🎉</p>
<p>Actually, neither.</p>
<p>Over a cold Christmas break back home in Montana, <strong>I realized I failed Calculus for two reasons.</strong></p>
<p>First, I wasn’t prepared. I didn’t understand the “language” of Calculus. Unlike most of my college classmates, I hadn’t taken a pre-Calculus course in high school. That put me at a serious disadvantage as I was unfamiliar with concepts such as limits, derivatives, and integrals.</p>
<p>Secondly, my Calculus teacher was dull and boring. And that’s not a personality you want teaching a 7am course to 19 year olds! 😴 It didn’t help that he had a thick Russian accent. I can still hear his voice, willing me to fail.</p>
<p><strong>Instructors of technical topics seem to fall into two categories.</strong></p>
<p>They’re either like Ferris Bueller’s teacher Mr. Lorensax or Doc Emmett Brown. You remember them from the 1980’s movies, right?</p>
<figure>
<img src="/images/blog/2020/06/lorensax.jpg" width="500" />
</figure>
<p><a href="https://www.youtube.com/watch?v=uhiCFdWeQfA" target="_blank">Mr. Lorensax</a> was the archetypical Economics teacher in the comedy <a href="https://www.youtube.com/watch?v=KS6f1MKpLGM" target="_blank">Ferris Bueller’s Day Off</a>. Monotonous. Mundane. Mind-numbing. 😵 Assign someone like Mr. Lorensax the job of teaching an exciting programming language and it would go like this:</p>
<p>“Bueller?”
“Bueller?”
“This is a string…”
“This is an integer…”
“This is a function…”
“Anyone?”
“Anyone?”</p>
<p>Sorry, Professor. We all decided to take the day off!</p>
<p>Or you can try learning from the zany <a href="https://www.youtube.com/watch?v=f-77xulkB_U" target="_blank">Doc Emmett Brown from Back To The Future</a>. He’s a genius alright, but nobody can seem to follow his logic.</p>
<figure>
<img src="/images/blog/2020/06/doc-emmett-brown.jpg" width="225" />
</figure>
<p>Even the time traveler Marty McFly can’t keep up as the eccentric Doc rambles on about 1.21 gigawatts, channeling energy, molecular structure, and flux capacitors. ⚡️</p>
<p>Put this guy in charge of teaching you Elixir and the syllabus would look like:</p>
<ul>
<li>
<p>Lecture #1: 1 + 1</p>
</li>
<li>
<p>Lecture #2: Asynchronous messaging between stateful GenServers</p>
</li>
<li>
<p>Lecture #3: Fault Recovery with OTP Supervisors for Flux Capacitors</p>
</li>
</ul>
<p>Whoa, Doc! Didn’t you leave something out between lectures #1 and #2? We were following along just fine and feeling good after the first lesson, and then whamo!</p>
<p>“Anyone?”
“Anyone?”</p>
<p><strong>You’re left hung out to dry when courses make the wrong assumption about your previous experience or have the wrong pace.</strong></p>
<p>In the same way I wanted to learn Calculus but wasn’t quite prepared, you may have jumped right into LiveView without being ready. I get it! 😀</p>
<p>It probably isn’t the LiveView programming model that’s tripping you up. If you’re struggling, it’s likely because you’re not yet comfortable enough with the Elixir language itself. So far in our <a href="/phoenix-liveview">Phoenix LiveView course</a>, the examples assume you know the following Elixir concepts and syntax:</p>
<ul>
<li>immutability</li>
<li>pattern matching</li>
<li>modules</li>
<li>named and anonymous functions</li>
<li>function clauses and guards</li>
<li>lists, maps, and structs</li>
<li>comprehensions</li>
<li>transformations and the pipe operator</li>
<li>using Enum to process collections</li>
</ul>
<p><strong>Indeed, writing even a basic LiveView assumes you know a whole bunch about Elixir and functional programming.</strong></p>
<p>And we’re only halfway through the LiveView course! In upcoming examples you’ll see more advanced Elixir and we’ll use parts of OTP including GenServers and Supervisors. As you’re probably realizing, the key to firing up LiveView in your own app is feeling confident with Elixir and OTP.</p>
<p>So how do you get that confidence?</p>
<p>Well, if you’re like me, the thought of enduring yet another programming language course is simply dreadful. Too many are either mind-numbingly slow or mind-blowing fast. 😩</p>
<p>What if there was a way to learn Elixir that was approachable and engaging?</p>
<p>A kind of sweet spot. You know the one. It’s when a course:</p>
<ul>
<li>
<p>is perfectly paced to meet you where you’re at</p>
</li>
<li>
<p>takes a practical project-based approach, not a sluggish syntax-approach</p>
</li>
<li>
<p>deconstructs underlining mechanics before introducing abstractions</p>
</li>
</ul>
<p>I found that sweet spot during my spring semester of college. I got my hands on some study guides that met me where I was in terms of experience. They helped me understand the Calculus way of thinking. And then I re-enrolled in Calculus but chose a different instructor who had a reputation for making Calculus approachable, practical, and even fun!</p>
<p>🍯 Our video course puts you in the sweet spot of learning Elixir and OTP.</p>
<p>It’s not too slow and it’s not too fast. It’s paced just right to keep you engaged and rapidly moving toward your goal.</p>
<blockquote>
<strong>"Most courses have the wrong pace for experienced devs. Yours is balanced perfectly</strong> (enough detail to learn and not get lost, but also a relatively fast pace and focus on idiomatic aspects)."
<cite>
<a href="https://twitter.com/weralabaj/status/1237771613845815297?s=20" target="_blank">Weronika Łabaj</a>
</cite>
</blockquote>
<p>In our Elixir and OTP course, we build a full-featured app step-by-step, from start to finish. You see every move, every change, and every refactoring firsthand.</p>
<blockquote>"<strong>You kept me interested at every step and I now understand complex concepts I never thought I would.</strong> You opened a whole new way of thinking for me."
<cite>
Josef Richter
</cite>
</blockquote>
<p><strong>You’ll come away ready to ace LiveView!</strong> And you’ll have the confidence to build pretty much anything with Elixir and OTP.</p>
<blockquote>
"Really enjoying the @pragmaticstudio Elixir course. <strong>It doesn't waste any time.</strong> I also like that the main thing built is a web server, which <strong>gives some insight into Phoenix</strong>. Highly recommend!"
<cite>
<a href="https://twitter.com/iamdtang/status/1087195743251648513" target="_blank">David Tang</a>
</cite>
</blockquote>
<p>If you like how Nicole and I teach, then we think you’ll love our <a href="https://pragmaticstudio.com/courses/elixir">Elixir & OTP course</a>. You get:</p>
<ul>
<li>6 hours of live-coding videos</li>
<li>22 narrated animations</li>
<li>56 hands-on exercises</li>
<li>all the source code, of course</li>
<li>lifetime access!</li>
</ul>
<figure>
<a href="/courses/elixir">
<img src="/images/courses/elixir-large.png" width="300" />
</a>
</figure>
<p>As for my adventures in Calculus, things went a lot smoother the second semester. I aced Calculus I (whew!) and, much to my surprise, I went on to ace Calculus II the next semester. And that put me back on track to earning my degree.</p>
<p>Along the way I learned a valuable lesson: <strong>You can learn almost anything with the right material and instructor.</strong> ⭐️</p>
<p>We hope you’ll join us in the Studio to <a href="https://pragmaticstudio.com/courses/elixir">learn Elixir & OTP</a>!</p>
LiveView Course Update #8: Pagination and SortingThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/06/17/liveview-course-update-82020-06-17T00:00:00Z2020-06-17T00:00:00Z<p>Hey there,</p>
<p>We’re back with another update on our <a href="/phoenix-liveview">Phoenix LiveView course</a>. This week we have two new examples for you!</p>
<h3 id="pagination-and-sorting-examples">Pagination and Sorting Examples</h3>
<p>Imagine you’re running a food bank that receives a lot of donations. A good problem to have, right? You have sooooo many donations in fact you now want to:</p>
<ul>
<li>paginate the list</li>
<li>change the number of donations shown per page</li>
<li>dynamically update the URL so you can share links to pages</li>
<li>sort the donations by various categories</li>
</ul>
<p>And you want to do all this without full page reloads? Well, no problem. LiveView is up to the task!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/06/liveview-sort.png" width="600" />
</a>
</figure>
<p>This week’s two new videos show you how to implement pagination and sorting. If you’ve already picked up a copy of the course, you’ll find these new modules in your account today.</p>
<h3 id="separate-liveview">Separate LiveView</h3>
<p>Up to this point in the course we’ve been co-locating each template directly inside the LiveView’s render function. But many of you have asked: “How do you put LiveView templates in separate files?”</p>
<p>It’s super easy, and we’ll show you how in these two examples.</p>
<h3 id="may-we-make-a-suggestion">May We Make A Suggestion…</h3>
<p>Don’t try to code along with us, at least not the first time through these videos. It’s easy to get lost in the code and miss the big picture when your focus is on getting the right name in the right function with the right closing } or ] or > syntax. We know this because we’ve done it ourselves. 🤦🏼♀️</p>
<p>Allow yourself instead to initially just watch the videos. No stopping, starting, rewinding, or hands on the keyboard. Try to get a good mental model in your head or even sketched on a piece of paper. By understanding the design of the forest first, you’ll be in a much better position to work with the individual trees.</p>
<p>For hands-on practice this week, here are a few options:</p>
<ul>
<li>
<p>pop open the final version of the code in your editor and walk through it</p>
</li>
<li>
<p>re-create the food bank examples from scratch</p>
</li>
<li>
<p>work through the exercises we give you for paginating and sorting a large list of vehicles</p>
</li>
</ul>
<h3 id="next-up">Next Up</h3>
<p>We are now over halfway through rolling out our free Phoenix LiveView course 🥳 Next up, we’ll roll out examples on live form validation, toggling state, and real-time notifications.</p>
LiveView Course Update #6: Live NavigationThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/06/03/liveview-course-update-62020-06-03T00:00:00Z2020-06-03T00:00:00Z<p>Hi Friends,</p>
<p>We write this newsletter with heavy hearts. We are conflicted about sending it.</p>
<p>The racism, injustice, and inequality that is soaked into the soil of our country is wrong. As followers of Jesus, it is entirely antithetical to what Mike and I believe. We believe Black Lives Matter.</p>
<p>To that end, we are thinking deeply about our role and how to do more (and better!) at standing in solidarity with those in the Black community, seeking justice and equality, holding ourselves and others accountable, and doing so with much humility.</p>
<p>The prayer of Desmond Tutu has been on our hearts this week:</p>
<blockquote>
Disturb us, O Lord<br />
when we are too well-pleased with ourselves<br />
when our dreams have come true because we dreamed too little,<br />
because we sailed too close to the shore...<br />
Stir us, O Lord<br />
to dare more boldly, to venture into wider seas...<br />
</blockquote>
<p>At the same time, we made a commitment to you to release new videos in our <a href="/phoenix-liveview">Phoenix LiveView course</a> as we complete them. Thank you for sticking with us. So while LiveView isn’t top of mind right now (nor should it ever be) we’d like to share with you a new video this week.</p>
<p>Based on our last update you’re most likely expecting a new video on either pagination or sorting with LiveView. Well, a funny thing happened along the way.</p>
<p>In the last two weeks we’ve rewritten the code for the pagination and sorting examples not once, but roughly 6 times. It’s not because the examples are difficult, but with each iteration we discovered new things which lead to new questions. 🤔 We dug deep into LiveView’s source code and exchanged emails with Jośe Valim (co-creator of Phoenix LiveView).</p>
<p>We also wrestled with duplication in our code. Sometimes our refactoring produced beautiful, easy-to-read code. Other times we ended up with a convoluted mess of indirection. Our Git commit log is quite lengthy. 😜</p>
<p>Each day, though, the code got better.</p>
<p>While reworking the code we were also reworking the video script. Do we teach the live_patch function before the handle_params callback or vise versa? Which one motivates the other? Does it make more sense to start with the URL params or the live navigation links?</p>
<p>Our aim is always to break things down into one concept at a time, one clear explanation at a time, one “AHA!” moment at a time. But that was proving to be more challenging than usual.</p>
<p>Up, down, and ‘round and ‘round we went. With each rewrite, though, the explanations got clearer.</p>
<p>And then last Thursday afternoon when we thought we might be done, despite a few lingering concerns, we checked in the final version and went fishing. 🎣</p>
<p>It’s funny what happens when you stop intentionally thinking about a hard problem and leave it to simmer in the back of your brain. Fishing is perfect for that sort of thing. While you concentrate on simply casting and reeling, your subconscious gets a chance to work through complex problems.</p>
<p>That’s when we realized our pagination and sorting examples made too big of a leap. Introducing live_path, live_patch, push_patch, and handle_params for a URL with 4 params spread across 2 Elixir maps on a page with multiple navigation links was too much to teach at once. 🤯</p>
<p>What if instead we started with a simpler example using just one new function and one new callback? It turns out, that’s all you need to implement basic live navigation. It’s a perfect stepping stone leading to pagination and sorting.</p>
<p>So this week’s new video shows you how to implement page navigation without a full page reload using LiveView. If you’ve already picked up a copy of the course, you’ll find this new module (#10) in your account today.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/06/liveview-servers.png" width="600" />
</a>
</figure>
<p>With a solid understanding of live navigation, you’ll be ready to dive into pagination and sorting next. At least that’s the plan as of this moment. 😉</p>
LiveView Course Update #4: FilteringThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/05/13/liveview-course-update-42020-05-13T00:00:00Z2020-05-13T00:00:00Z<p>Hey there,</p>
<p>We’re back with another update about our <a href="/phoenix-liveview">Phoenix LiveView course</a> (see updates <a href="/blog/2020/04/14/liveview-course-update-1">#1</a>, <a href="/blog/2020/04/21/liveview-course-update-2">#2</a>, and <a href="/blog/020/05/04/liveview-course-update-3">#3</a>).</p>
<p>Let’s start with the most significant news…</p>
<h3 id="new-example-filtering">New Example: Filtering</h3>
<p>This week’s new video shows you how to filter data with LiveView, and get snappy results. In light of the quickly approaching summer season here, we went with a boat theme. ⛵️</p>
<ul>
<li>and we finally put something in the database.</li>
<li>and we tossed in a hot performance tip.</li>
<li>and there are 5 exercises!</li>
</ul>
<p>Woohoo!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/05/liveview-boat.png" width="500" />
</a>
</figure>
<p>If you’ve already picked up a copy of the course, you’ll find this new module (#9) in your account today. You’ll need to download the new code bundle which has the begin and end branches for this example, as well as new CSS bits.</p>
<h3 id="new-exercise-colorize-your-light-">New Exercise: Colorize Your Light 💡</h3>
<p>We added a fun new exercise to module #7. Light temperature is a personal preference, and helps to set the right mood. So given what you’ve learned up to this point, you can return to the light controller and add radio buttons to set the right temperature for the occasion. Brilliant!</p>
<h3 id="javascript-integration-ideas">JavaScript Integration Ideas</h3>
<p>Last week we asked you for ideas and boy, did you deliver! Thank you! We got a lot of great ideas and we’re currently tinkering with them. Stay tuned…</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/05/liveview-map.png" width="400" />
</a>
</figure>
<h3 id="how-will-liveview-scale">How will LiveView scale?</h3>
<p>🤔 It’s a fair question, especially if you’re new to the Elixir/Phoenix platform. Since each stateful LiveView runs in a separate process, depending on the number of users you could have thousands, hundreds of thousands, or even millions of processes. And all the communication happens over Websockets.</p>
<p>A lot of systems would buckle under these conditions, but Elixir and Phoenix are uniquely suited for it. And by riding atop this battle-tested platform, LiveView is in a league of its own.</p>
<p><a href="https://www.phoenixframework.org/blog/the-road-to-2-million-websocket-connections" target="_blank">The Road to 2 Million Websocket Connections in Phoenix</a> has a lot of juicy details.</p>
<p>Thanks again for following along with us. We hope you’re having a blast with LiveView! 🚀</p>
LiveView Course Update #3: FAQThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/05/04/liveview-course-update-32020-05-04T00:00:00Z2020-05-04T00:00:00Z<p>We are so thankful for YOU…</p>
<p>…for being interested in our <a href="/phoenix-liveview">Phoenix LiveView course</a></p>
<p>…for snagging a copy of the course during early access (that’s most of you)</p>
<p>…for overwhelming us (in a good way) with your response!</p>
<p>⭐️ You are AMAZING!</p>
<p>We’ve never received this much feedback so early in a course. Please keep it comin’. And if you’re finding the course helpful or inspiring, it would mean the world to us if you’d help spread the word. 🧡</p>
<p>It’s proving to be unlikely that we’ll be able to respond to everyone personally and still set aside large chunks of time to work on the upcoming LiveView examples. ⚖️ But please know that we read every single piece of feedback.</p>
<p>Since many of the same questions keep popping up, we thought it’d be a good time for another update. (Course updates <a href="/blog/2020/04/14/liveview-course-update-1">#1</a> and <a href="/blog/2020/04/21/liveview-course-update-2">#2</a>)</p>
<h3 id="first-up-how-do-i-install-and-configure-tailwind-css">First up, how do I install and configure Tailwind CSS?</h3>
<p>Some of you wanted to know the exact steps we took to install and configure Tailwind CSS so you could create a Phoenix app similar to the one in the <code>1-button-clicks-begin</code> branch.</p>
<p>You betcha. 👍</p>
<p>See our step-by-step <a href="https://pragmaticstudio.com/tutorials/adding-tailwind-css-to-phoenix">Adding Tailwind CSS to Phoenix</a> tutorial. We also added a link to this in the Setup notes.</p>
<h3 id="dude-im-a-lazy-typer-can-i-get-the-initial-html-pasted-in-render">Dude, I’m a lazy typer! Can I get the initial HTML pasted in <code>render</code>?</h3>
<p>Indeed, you can! We’ve updated the Notes for each video to include an “Initial Template” section where you’ll find the initial template we pasted into <code>render</code>.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/05/liveview-10.png" width="294" />
</a>
</figure>
<p>Save all that typing for the good stuff! 👊</p>
<h3 id="wait-why-did-you-have-us-install-postgresql">Wait, why did you have us install PostgreSQL?</h3>
<p>In the setup exercise we had you install PostgreSQL. A few folks astutely pointed out that we don’t need it since none of the examples use a database.</p>
<p>And that’s true, until we get to the <strong>next</strong> example! ⛵️</p>
<p>Starting in Example #6 we’ll persist the example’s data in a PostgreSQL database and use Ecto to query it. And we’ll continue using a database in subsequent examples. In the initial examples we wanted to focus on LiveView core concepts without having to create database migrations, schemas, and the like.</p>
<p>Anyway, we get all the system-level stuff installed upfront so it doesn’t bog us down later.</p>
<h3 id="how-will-i-know-when-new-examples-are-released">📣 How will I know when new examples are released?</h3>
<p>Since you’re on this mailing list, we’ll send you an email! You can also follow <a href="https://twitter.com/pragmaticstudio" target="_blank">@pragmaticstudio</a> on Twitter for updates. And Mike (<a href="https://twitter.com/clarkware" target="_blank">@clarkware</a>) posts various bits and bobs if you want micro-updates.</p>
<p>We’ll incrementally roll out videos and exercises as we complete them, and they’ll automatically show up in your account.</p>
<p>So sit back, relax, and we’ll deliver fresh examples wherever you’re hanging out! 🏡🏖⛺️</p>
<h3 id="hey-are-you-planning-to-create-examples-on">Hey, are you planning to create examples on…</h3>
<h3 id="real-time-notifications">Real-Time Notifications?</h3>
<p>Absolutely! It’s a critical part of LiveView. Example #10 will laser-focus on the fundamentals of notifying users when relevant changes occur, and later examples will build on it.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/05/liveview-9.png" width="600" />
</a>
</figure>
<h3 id="authentication">Authentication?</h3>
<p>How did you guess? It’s on the list, currently slated as Example #13!</p>
<h3 id="components">Components?</h3>
<p>Pity, only one of you asked about this. Just kiddin’. 😂</p>
<p>Clearly components are a big deal to nearly all of you. <strong>Trust us, we’ll get there!</strong> We had to lay a good foundation so when we get to components you’re not trying to learn 10 things at once.</p>
<h3 id="javascript-integration">JavaScript Integration?</h3>
<p>We’d love to❗️and you can help us. The thing is, we haven’t yet identified a great example: one that’s common, realistic, and not super complex. Watching us type out a bunch of JS isn’t going to be pleasant. Hooking into a library might be sufficient. Maybe something with charting?</p>
<p>Please let us know if you’ve got any bright ideas.💡</p>
<h3 id="what-about-testing">What About Testing?</h3>
<p>Hmm… we didn’t plan on making a video specifically about testing. It’s a bit of slippery slope. It’s difficult to do testing any justice in a single video. So then it turns into 2-3 videos. And before long you realize it should be an entire course on its own. Does it sound like we’ve slid down that slope before? ⛷</p>
<p>That being said, LiveView has a great testing story. It would be a shame not to do something around testing. Perhaps we’ll write tests for one of the more interesting examples.</p>
<h3 id="will-there-be-a-capstone-application-at-the-end">Will there be a capstone application at the end?</h3>
<p>A few of you wondered if we’d cap off the course by building a real-life application end-to-end. A big, put-it-all-together app. One that uses all the techniques we learned in the examples. A 4-course meal with white linen. 🍽 🥂</p>
<p>No, and yes!</p>
<p>This course won’t end with a big capstone application. We explicitly designed this course around focused, isolated examples. Think of them as recipes. You can jump in, snack on what you need, and then build your own amazing things. 🙌</p>
<p>On the other hand, we do have a full-featured application we want to build from the ground up with LiveView. It’ll probably take 4+ hours to build step-by-step. And that feels like a totally different course. 😉</p>
<p>Thanks again for following along with us. We hope you’re having fun with LiveView!</p>
LiveView Course Is Live!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/04/30/liveview-course-early-access2020-04-30T00:00:00Z2020-04-30T00:00:00Z<p>Today we opened early access to our free <a href="/phoenix-liveview">Phoenix LiveView course</a>. The first 7 videos (75 minutes) along with their corresponding exercises and notes are ready for you! New videos and examples will be released incrementally as they’re ready in upcoming weeks.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/courses/liveview-large.png" width="400" />
</a>
</figure>
<h3 id="wait-what-is-liveview-again">Wait, what is LiveView again?</h3>
<p>The short answer is that LiveView enables you to build Phoenix apps that have interactive, real-time user experiences without writing JavaScript.</p>
<p>To really understand what that means, it’s helpful to compare and contrast LiveView with something you already know. So our <a href="/phoenix-liveview">first video</a> looks at how LiveView is similar and different from Ajax. And we think you’ll see how LiveView is really unique!</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/04/liveview-1.png" width="500" />
</a>
</figure>
<h3 id="our-gift-to-you-">Our Gift To You 🎁</h3>
<p>Yup, we’re giving away this course! It’s 100% free with no strings attached. Not because the course doesn’t have value. We think it has a <strong>ton</strong> of value!</p>
<p>So far we’ve sketched out <strong>13 common UI challenges</strong> that LiveView neatly solves. You can slip these code examples right into your own Phoenix app. Here are the first 5 examples included in early access:</p>
<figure>
<img src="/images/blog/2020/04/liveview-3.png" width="500" />
</figure>
<figure>
<img src="/images/blog/2020/04/liveview-4.png" width="500" />
</figure>
<figure>
<img src="/images/blog/2020/04/liveview-5.png" width="500" />
</figure>
<figure>
<img src="/images/blog/2020/04/liveview-6.png" width="500" />
</figure>
<figure>
<img src="/images/blog/2020/04/liveview-7.png" width="500" />
</figure>
<p>We’ve also created some nifty <strong>exercises</strong>. They build up progressively as you learn new things so you can apply what you’ve learned in different ways.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/04/liveview-8.png" width="500" />
</a>
</figure>
<p>This is the <strong>step-by-step, approachable course</strong> we wish we’d had when wrapping our heads around LiveView last year.</p>
<p>But what convinced us to offer up this course for free was LiveView’s <strong>simple (almost addictive!) programming model</strong>. José Valim, Chris McCord, and contributors to LiveView have done an incredible job creating a library that is both really fun to use and really powerful. 🤩</p>
<p>The benefits of using LiveView are dramatic:</p>
<ul>
<li>both client and server in sync, always and seamlessly</li>
<li>persistent connections highly-optimized for web scale</li>
<li>robust and resilient UIs so you can rock and roll</li>
<li>a unified code base that’s easier to maintain</li>
<li>no custom JavaScript or external dependencies</li>
</ul>
<p><strong>It’s a total game-changer!</strong></p>
<p>We hope you’ll join us to learn LiveView and also help spread the word about this <a href="/phoenix-liveview">free course</a>. Your friends will love you for it! 😉</p>
LiveView Course Update #2: New ReleasesThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/04/21/liveview-course-update-22020-04-21T00:00:00Z2020-04-21T00:00:00Z<p>Hey again, we’re back with another update on our <a href="/phoenix-liveview">Phoenix LiveView course</a>. 🔥</p>
<h3 id="one-domain-vs-many-domains">One Domain vs Many Domains</h3>
<p>When we make our comprehensive language or framework courses, we build a single app from scratch. That means we have to select one domain in which to convey everything we want to teach. In our <a href="/courses/rails">Rails course</a>, for example, we explore all the ins and outs of Rails within the context of an event registration app. 📅 In our <a href="/courses/elixir">Elixir course</a> the domain is an HTTP web server. ⚡️</p>
<p>Last year when we started work on our Phoenix course, we again had to settle on one domain. As LiveView then began to heat up we knew it would play a big role in the course. So a few months ago we immersed ourselves in LiveView and started building a dozen or so examples demonstrating different facets of LiveView. But we quickly realized that all these examples wouldn’t make sense in the domain we picked for the Phoenix course. Alas, some of them would end up on the cutting room floor. 😩</p>
<p>By creating a separate LiveView course, we have a lot more freedom with domains. And it’s been really fun! So far we have everything from 💡 light controllers to ⛵️ boat rentals to 🍓food banks.</p>
<p>This week we finished up work on 2 new examples…</p>
<h3 id="example-3-sales-dashboard">Example #3: Sales Dashboard</h3>
<p>In contrast to the first two LiveView examples which update in response to user-generated events (button clicks and form changes), this third example updates in response to internal messages. We create a live dashboard with three sales metrics:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/04/liveview-5.png" width="600" />
</a>
</figure>
<p>👀 To help us keep a watchful eye on these stats, the LiveView automatically updates the stats on a periodic interval.</p>
<h3 id="example-4-live-search">Example #4: Live Search</h3>
<p>In the good ol’ days of 2019 (before 😷) when people went out shopping and dining, you probably used the feature that is our fourth example. It’s fairly common for a store or restaurant’s website to allow you to look up nearby locations, like so:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/04/liveview-6.png" width="600" />
</a>
</figure>
<h3 id="liveview-and-phoenix-15-updates">LiveView and Phoenix 1.5 Updates</h3>
<p>Now you might be thinking “Hey Mike and Nicole, two examples isn’t a lot of progress since last week’s update.” And that’s possibly true, but sometimes you have to go backwards to go forwards!</p>
<p>Case in point, <a href="https://elixirforum.com/t/phoenix-1-5-0-rc-0-released/30693" target="_blank">Phoenix 1.5.0-rc.0 was released</a> last week. 🥳 We’ve been awaiting this release because it has some cool new features including seamless integration with Phoenix LiveView as well as the new Phoenix LiveDashboard. That means out-of-the-box Phoenix apps generated with the <code>--live</code> option have all the LiveView goodies included. In addition, a minor version of LiveView was released last week.</p>
<p>And we’re on top of it! We went back through all our examples and made the necessary updates for these releases.</p>
<h3 id="a-bundle-of-branches">A Bundle of Branches</h3>
<p>Last week we also settled on how to organize the course code bundle. We had two concerns. First, we didn’t want each LiveView example to be a separate Phoenix app. That felt like overkill, and it makes updating to new versions a pain.</p>
<p>However, putting all the examples in one Phoenix app presented another problem.
Some of the more involved examples have supporting files such as a Phoenix context module, an Ecto schema, a database migration file, and so on. And that’s a lot of code to wade through, especially when you’re getting started.</p>
<p>So we decided to use Git branches with one Phoenix app. For each example there are two branches, like so:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>1-button-clicks-begin
1-button-clicks-end
2-dynamic-form-begin
2-dynamic-form-end
3-sales-dashboard-begin
3-sales-dashboard-end
4-search-begin
4-search-end
</code></pre></div></div>
<p>The naming convention isn’t too hard to figure out. 😉 The branches with “begin” are the starting points for each example. And the branches with “end” contain the corresponding example’s final code.</p>
<p>Using branches this way allows us to introduce the relevant files incrementally. It also makes it easy for you to get a diff of all the changes for a specific example.</p>
<p>How’s that sound to you?</p>
<h3 id="new-studio-equipment">New Studio Equipment</h3>
<p>The other thing we worked on wasn’t what you <em>see</em> but what you <em>hear</em>. 🎧</p>
<p>We recently moved The Pragmatic Studio’s worldwide HQ (aka our home office) and built a new soundproof recording studio.</p>
<p>We also purchased two Shure SM7B microphones, two Heil PL2T microphone booms, and a Focusrite Scarlett 2i4 mixer. The SM7B notoriously needs more gain than most mics. We know many of you watch our videos on planes, trains, and subway cars (back before 🦠 kept us at home), and it’s important that you get good, clean audio at the right level. So we added two Triton Audio FetHead preamps to boost the gain.</p>
<p>The audio is much better now in this new location!</p>
<h3 id="yeah-so-when-will-it-be-done">Yeah, So When Will It Be Done?</h3>
<p>Depending on the needs of those around us and our continued health, we’re hoping to record a handful of modules this week. If we get on a roll without any hiccups, we might have the first round of videos ready for you next week. 🤞🎤</p>
<p>Finally, to all of you who have written back with suggestions, questions, and comments: Thank you! 🧡 Keep ‘em coming.</p>
LiveView Course Update #1: What Is It?The Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/04/14/liveview-course-update-12020-04-14T00:00:00Z2020-04-14T00:00:00Z<p>Hey there!</p>
<p>Thanks for your interest in our upcoming free <a href="/phoenix-liveview">Phoenix LiveView course</a>.</p>
<p>We’re looking forward to keeping you in the loop on where we’re at on course development. We’d also like to use these periodic updates as a way to dialogue with you about LiveView. We’ll share our thoughts, rationale for choosing one approach over another, and maybe even pose a question or two. In return, we’d love to hear about your experiences or questions with LiveView.</p>
<p>🐘 Let’s start with the big elephant in the room…</p>
<h3 id="when-will-it-be-done">When Will It Be Done?</h3>
<p>It depends on what you mean by “done.” Our plan is to roll out an initial batch of videos (perhaps the first 6 examples), and then incrementally release the remaining examples currently listed in the <a href="/phoenix-liveview">preliminary course outline</a>. But we probably still won’t be “done.”</p>
<p>We might then add a new example we didn’t think of when planning the course. As well, we’re hoping you might suggest examples that we overlooked. 😉 And as LiveView changes, we expect we may have to redo some videos to keep the course up to date. So at this point “done” is a moving target.</p>
<p>However, given the progress we’ve made these past couple weeks, fingers crossed 🤞🏻 we’re hoping to have the initial batch of videos ready within the next month. Might be sooner, but could also be later. Simply put, we’re not far enough along to make a solid prediction. And as we’re all experiencing right now, certainty is an illusion.</p>
<p>Thank you for your support and patience!</p>
<h3 id="whos-it-for">Who’s It For?</h3>
<p>We ask ourselves this very-important question before creating any course. 🤔 The answer determines both the content and the pace of the course. A course made for everybody satisfies nobody. So we have to decide who we’re making the course for, which implicitly means it’s not made for others. It’s a tough decision!</p>
<p>In terms of LiveView, do we assume:</p>
<ul>
<li>you’ve only heard of LiveView, but don’t know why you might use it?</li>
<li>you’re an experienced Elixir and Phoenix developer… or not?</li>
<li>you’re already using LiveView and just want to see more examples?</li>
</ul>
<p>In the end we decided to keep this course focused and paced for developers who ✅ already know Elixir and Phoenix, but ❌ don’t know anything about LiveView. And even if you’re already using LiveView, we think you’ll get a lot of value out of seeing it used to solve other problems.</p>
<h3 id="what-is-liveview">What Is LiveView?</h3>
<p>One of the most expedient ways to learn something new is by comparing and contrasting it with something you already know. Your brain is wired to learn that way. So that’s the approach we took in our first video using Ajax as the baseline. We hope you’ve had a chance to check it out:</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/04/liveview-1.png" width="500" />
</a>
</figure>
<p>We have a love/hate relationship making explainer videos like this using animation. 😍 We’re visual learners, so we <strong>love</strong> breaking down the concepts into a visual representation. Because once you start seeing code, it’s too easy to get lost in the syntax details. Don’t worry, there’s plenty of code in the course! But that’s not a good starting point.</p>
<p>😩 The <strong>maddening</strong> part about making animations is it takes a TON of time and rework. A 3-minute explainer video can easily take us 3 days to make, and that’s if we have a trailing wind. In the end we think the animations are worth it, but they sure do drive us crazy at times!</p>
<h3 id="lifecycle-animation-almost-complete">Lifecycle Animation Almost Complete</h3>
<p>Speaking of challenging animations, this past week we worked on the second animated video in the course. It breaks down the details of a LiveView’s lifecycle and highlights what makes LiveView unique.</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/blog/2020/04/liveview-2.png" width="480" />
</a>
</figure>
<p>It’s important to us that we get this right and not inadvertently spread any misconceptions about LiveView, so we’ve reached out to <strong>José Valim</strong> (co-creator of LiveView) to get his feedback. He’s been gracious enough to review both animations and suggested excellent changes. We’ve gone through a couple rounds of edits (video edits are always costly) and there’s no doubt it has made the animations better.</p>
<p>We’re super thankful for José’s support of this project❗️</p>
<h3 id="first-example-light-controller">First Example: Light Controller</h3>
<p>Our first LiveView example is a simple light controller:</p>
<figure>
<img src="/images/blog/2020/04/liveview-3.png" width="500" />
</figure>
<p>It’s basically a glorified counter, but it’s a great way to get our feet wet with LiveView’s mount, render, and handle_event callbacks. You can turn the light on and off, or dim it up and down.</p>
<h3 id="second-example-team-license-calculator">Second Example: Team License Calculator</h3>
<p>Our second example is a simple dynamic form for calculating the price of a team license:</p>
<figure>
<img src="/images/blog/2020/04/liveview-4.png" width="500" />
</figure>
<p>Move the slider and multiple values change. It’s a great starting point for building more sophisticated forms later on in the course.</p>
<p>That’s it for now. Got questions or thoughts? We’d love to hear them. 😄</p>
What We're Doing While Stuck At Home: Phoenix LiveViewThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/03/31/what-were-doing-while-stuck-at-home2020-03-31T00:00:00Z2020-03-31T00:00:00Z<p><strong>Hi Friends,</strong></p>
<p>We sincerely hope you are safe and well. It’s tough out there. People are hurting. The future feels more uncertain. Normal life has been disrupted.</p>
<p>And yet there is hope. Hope that the steps we’re taking now lead to a healthier tomorrow. Hope that the illusions or priorities in our lives that needed a disruption are more wisely reconstructed. Hope that since we’re all in this together we’ll learn to live and work better together. 🕊</p>
<p>All we know to do right now is to love our neighbors, find a way to respectfully reach across the social distance, and continue (as time and health permits) to be creative and do our best work.</p>
<p><strong>Working From Home, As Always</strong></p>
<p>Mike has worked from home for over two decades, and I (Nicole) made the move from a corporate desk to wearing slippers in our home office fifteen years ago. 🏡 So thankfully, when our statewide stay-at-home order went out, we were already accustomed to creating, learning, and teaching new things from home.</p>
<p><strong>Building LiveView Examples</strong></p>
<p>Last year we started working on a Phoenix course, and as <a href="https://github.com/phoenixframework/phoenix_live_view">LiveView</a> began to heat up we knew it would play a big role in the course. So a few months ago we immersed ourselves in LiveView.</p>
<p>The simple programming model makes it a really fun library to use. 🎉 So much fun, in fact, that we couldn’t seem to stop using it to build all sorts of interactive UI features that traditionally require custom JavaScript. Things like reacting to button clicks, form validation, autocomplete, and real-time updates.</p>
<p>After building a dozen or so of these features, we realized they wouldn’t all make sense in the application we created for the Phoenix course. Some of the LiveView examples would end up on the cutting room floor. 😣</p>
<p>But then Mike thought, “Hey, we could turn this into a fun and practical mini-course!” So that’s exactly what we’re doing while stuck at home. 👍🏻</p>
<figure>
<a href="/phoenix-liveview">
<img src="/images/courses/liveview-large.png" width="400" />
</a>
</figure>
<p><strong>It’s a Free Course!</strong></p>
<p>Initially we didn’t know if a <a href="/phoenix-liveview">Phoenix LiveView course</a> would be paid or free. It’s now clear to us that we want to make it available for free. While we believe the course offers a lot of value—so far we have 3 detailed animations and 12 code examples for you—we want to offer it as a gift. 🎁</p>
<p><strong>First Video Now Available</strong></p>
<p>To get things rolling, today we’re releasing a 4-minute animated video answering the question “What Is LiveView?” <a href="/phoenix-liveview">Check it out</a>, along with a preliminary course outline, and let us know what you think.</p>
<p><strong>Get Progress Reports</strong></p>
<p>If you want to get updates and a behind-the-scenes view on our progress as we finalize the course, please <a href="/phoenix-liveview">add your email to the mailing list</a>. It would also be encouraging to hear that you’re interested. 😉</p>
<p>People need access to good online, educational material, perhaps now more than ever. 👩💻 And, as always, we’re committed to doing what we can to contribute with high-quality, concise videos. We hope to see you in the Studio soon!</p>
<p>May you have good health and peace in these times,</p>
<p>~ Nicole & Mike</p>
Spring Into Elixir and OTP For Free This WeekThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/03/10/spring-into-elixir-for-free-this-week2020-03-10T00:00:00Z2020-03-10T00:00:00Z<p>Sometimes getting started is the hardest part. Take our recent home improvement project for example.</p>
<p>Last fall we removed half the baseboard in our house for rework. After prying the boards off the walls, we carried the stacks downstairs and laid out all the pieces on the basement floor.</p>
<p><strong>Seeing the project spread out before us like that was a little overwhelming.</strong> 😱 Rework was going to be a multi-step process:</p>
<ul>
<li>repair</li>
<li>sand</li>
<li>paint</li>
</ul>
<p>We were initially drawn to several less intimidating and smaller house projects, like hanging mirrors. 🔨 Meanwhile, our baseboard began to settle in for a long winter’s nap on the cold concrete floor.</p>
<p>Then one evening we decided to start the project with a little bit of putty and caulking. “Let’s just take an hour or so, play some good music and make a few repairs,” I said.</p>
<p><strong>Once we got over the initial hurdle we quickly found a comfortable rhythm:</strong></p>
<ul>
<li>find an interesting playlist on Spotify</li>
<li>fill the holes and cracks</li>
<li>replace sandpaper in the sander</li>
<li>give the boards a smooth finish</li>
<li>roll paint</li>
<li>admire our handiwork</li>
<li>repeat!</li>
</ul>
<p>Soon enough we were cruising along. Short boards, long boards, and corner pieces quickly moved from the beat-up stack to the looking-like-new pile. To our great relief, we actually completed this project long before winter started to show glimpses of spring.</p>
<p>If you have a similar overwhelming feeling 😩 when it comes to the project of learning Elixir , we’d like to help. Maybe all you need is someone to come alongside you and say ““Let’s just take 10 minutes and write a few lines of code.”</p>
<p>The first video in our Elixir and OTP course is 2 minutes and the second video is only 8 minutes. It’s a small hurdle we can jump together and this week you can do it for FREE. The first half of our <a href="/elixir">Developing With Elixir/OTP</a> course is open through Sunday, March 15!</p>
<figure>
<a href="/courses/elixir">
<img src="/images/courses/elixir-large.png" width="300" />
</a>
</figure>
<p>Our hope is that you’ll find an enjoyable rhythm of discovery:</p>
<ul>
<li>watch a short video</li>
<li>write some code</li>
<li>learn a new part of the language</li>
<li>watch another concise video</li>
<li>write some more code</li>
<li>experience an “Aha!” moment of understanding</li>
<li>repeat!</li>
</ul>
<p><strong>Before you know it, you can cross this project off your list.</strong> ☑️</p>
<p>Chaz Watkins recently wrote in to tell us:</p>
<p>“I loved that this course showed the primitives of Elixir and Erlang in detail before introducing the nice-to-have abstractions. This was fantastic for understanding the why behind the abstractions!”</p>
<p>If you find yourself cruising along and want to finish the course, we’d be delighted to have you along for the entire ride!</p>
<p>In the second half of the course, you’ll find that abstractions such as GenServers and supervisors quickly move from the mysterious stack to the “I totally get it now” pile.</p>
<p>Now that’s a great way to kick off spring! 😎</p>
4 Videos on Active Storage Added to Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2020/02/20/2-new-videos-active-storage-rails-62020-02-20T00:00:00Z2020-02-20T00:00:00Z<p>Earlier this month we decided to add Active Storage to our <a href="/courses/rails">Rails 6 course</a>. We figured on one new video around 10 minutes. Maybe two videos. It turns out we’re bad estimators. 🤦</p>
<p>When we got working on the actual details we quickly realized that there was more than meets the eye…</p>
<p>Our app already uses images in the Asset Pipeline, so we need to address the ramifications of <strong>switching from the Asset Pipeline to storing images in the cloud</strong>. Even then, not everything gets stored in the cloud. Active Storage uses two database tables and a polymorphic association. And it’s helpful to know how that works.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2020/02/rails-6-42-blog.png" width="500" />
</a>
</figure>
<p>Then, speaking of the cloud, it needs secure access to a developer’s <strong>super-secret credentials</strong>. And doing that right is important. We wouldn’t want you to accidentally leave your 🔑 key right on top of your treasure chest of secrets.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2020/02/rails-6-43-blog.png" width="500" />
</a>
</figure>
<p>And then there was that last innocent-looking bullet point on our original outline: <strong>Deployment</strong>. Now, Active Storage has a slick way of switching storage services on a per-environment basis, so deployment isn’t a huge deal. But it’s also not just a one-line command.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2020/02/rails-6-44-blog.png" width="500" />
</a>
</figure>
<p>Sure, we could have tried to jam all this into a single how-to video, but the pacing would be all wrong and you wouldn’t really understand why it all worked.</p>
<p>So fast-forward and we ended up putting together 4 new videos! We hope you find them helpful for implementing Active Storage in your own app.</p>
<p>Up, up, and away! 🌤</p>
Rails 6 Course Is Complete! 🚀 Special Launch PriceThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/11/07/rails-6-course-launches2019-11-07T00:00:00Z2019-11-07T00:00:00Z<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/11/rails-6-launch-price.png" width="700" />
</a>
</figure>
<p><strong>Our <a href="/courses/rails">Rails course</a> is now completely updated for Rails 6!</strong> Thank you all for your patience and feedback over the many months it took us to remake this 8-hour course. 😅</p>
<p>Our first priority was to update the topics from our initial course. With that now out of the way, we’re excited about adding new videos to the course in the coming months, perhaps including ActionText, ActiveStorage, Webpack, and other topics new with Rails 6.</p>
<p>You’ll <strong>learn how to pragmatically build and design Rails 6 apps from scratch</strong> with a project-based approach. The full course includes:</p>
<ul>
<li><strong>8 hours</strong> of live coding</li>
<li><strong>50 streamable and downloadable videos</strong> (all with English subtitles)</li>
<li><strong>48 chapter workbook</strong> with step-by-step exercises</li>
<li><strong>45 animations</strong> to give you a deeper understanding of how and why</li>
<li><strong>All the source code</strong>, of course!</li>
<li><strong>Never-ending access</strong> (no monthly subscription)</li>
</ul>
<p>We put hundreds of hours into redoing this course and our hope is you’ll feel empowered to now build your own awesome Rails 6 apps!</p>
<h3 id="final-videos-released-today">Final Videos Released Today</h3>
<h4 id="friendly-urls-and-callbacks">#40 Friendly URLs and Callbacks</h4>
<p>URLs are the user interface of the web. As such, they require intentional design. One common technique is to include <strong>meaningful and friendly names</strong> (rather than numeric ids) in resource URLs. We show you exactly how to do that, exploring Active Record callbacks along the way.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/11/rails-6-40.png" width="400" />
</a>
</figure>
<h4 id="deployment">#41 Deployment</h4>
<p>Putting your Rails app into production shouldn’t cause fear and trembling. Deploying Rails apps has gotten a lot easier over the years thanks in large part to cloud services such as Heroku. We’ll show you <strong>how to deploy your Rails app</strong> for the first time, and incrementally roll out application updates with ease!</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/11/rails-6-41.png" width="400" />
</a>
</figure>
<p>🚀 Enjoy!</p>
No Tricks, Just Treats! 4 New Videos Added to Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/10/31/no-tricks-just-treats-4-new-videos-rails-62019-10-31T00:00:00Z2019-10-31T00:00:00Z<p>Many-to-many associations as well as custom scopes and routes were never meant to trick you. But if they do, this week’s four new <a href="/courses/rails">Rails 6 videos</a> will turn them from tricks into tasty treats! 🎃 🍫</p>
<p>Many-to-many associations are so common that we <strong>design a 5th and 6th example</strong> to continue building your confidence with these types of relationships. We also explore <strong>how to write idiomatic and concise custom scopes and routes</strong> to help users find exactly what they’re looking for.</p>
<p>In Module #38 we design yet another many-to-many relationship. This time we use a <strong>through association in the models and a collection of checkboxes in the user interface</strong> to assign multiple categories to events and multiple genres to movies.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/10/rails-6-38.png" width="500" />
</a>
</figure>
<p>One approach to defining a custom query is to write a class-level method. But a more <strong>idiomatic and concise way to write a custom query</strong> is in a declarative style using the scope method. Doing so in Module #39 lets us slice and dice our events and movies into all sorts of interesting categories.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/10/rails-6-39.png" width="500" />
</a>
</figure>
<p>With our scopes in place for specific criteria, it’s time to show them off. We set up custom routes so that users can easily filter what they’re looking for.</p>
<p>🎃 Enjoy, and Happy Halloween!</p>
5 Videos on Many-to-Many Associations Added to Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/10/24/5-new-videos-many-to-many-rails-62019-10-24T00:00:00Z2019-10-24T00:00:00Z<p>Does the thought of correctly modeling rich many-to-many associations leave you a little frightened? 👻</p>
<p>Rails has powerful conventions to help you manage these relationships, but the conventions alone only take you so far. It’s up to you to model the associations with the full stack in mind: from the database tables all the way through to the user interface.</p>
<p><strong>But don’t be spooked!</strong> 😱</p>
<p>Today we released five new <a href="/courses/rails">Rails 6 videos</a> that dig into six different examples to chase your scary thoughts away.</p>
<p>Starting in Module #35 we streamline the registration process for currently signed in users by creating our <strong>first many-to-many association</strong> which connects a user to an event using a join model and a form.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/10/rails-6-35.png" width="500" />
</a>
</figure>
<p>In our <strong>second many-to-many association</strong> we make it possible for users to like multiple events with a button.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/10/rails-6-36.png" width="500" />
</a>
</figure>
<p>Which leaves us with a question: In the absence of a direct relationship between two models, how do you efficiently traverse between them? Thankfully, Rails offers a really convenient way: <strong>through associations</strong>. They can seem a bit magically at first, but we quickly dispel any confusion.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/10/rails-6-37.png" width="500" />
</a>
</figure>
<p>👻 Enjoy!</p>
3 Videos on Authorizing Users Added to Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/10/10/3-new-videos-authorization-rails-62019-10-10T00:00:00Z2019-10-10T00:00:00Z<p>We released three new <a href="/courses/rails">Rails 6 videos</a> for you today!</p>
<p>As our app stands, we have user authentication implemented and we know whether a user is signed in or not. Now it’s time to start <strong>restricting access to parts of the application</strong>. This process is commonly referred to as <em>authorization</em>. Authorization rules vary widely depending on the nature of the application, but once you understand the technique you can apply it as you see fit.</p>
<p>In Module #33 we put various <strong>gatekeepers</strong> (otherwise known as before actions) in place to restrict who can make changes.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/10/rails-6-33.png" width="500" />
</a>
</figure>
<p>Then in Module #34, we take it a step further by allowing only <strong>super-special admin users</strong> we trust to perform highly-sensitive actions in our app. So we distinguish admin users from regular users, and restrict access accordingly.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/10/rails-6-34.png" width="500" />
</a>
</figure>
<p>Enjoy!</p>
4 Videos on Authenticating Users Added to Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/09/26/4-new-videos-authenticating-users-rails-62019-09-26T00:00:00Z2019-09-26T00:00:00Z<p>When you sign in to a web app, how does it verify your identity and then remember that you’re signed in as you navigate from page to page? 🤔</p>
<p>Well, from the user’s perspective it seems like a pretty trivial thing. But the reality is there’s a lot going on behind the scenes. Implementing user authentication properly in Rails requires a good understanding of several moving parts: sessions, cookies, filters, secure passwords, and so on.</p>
<p>We break it all down in this week’s release of <a href="/courses/rails">four new Rails 6 videos</a> so you can implement authentication yourself or use a gem with confidence.</p>
<p>We start in module #29 by <strong>designing a sign-in form</strong> that lets registered users sign in using their email and password.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/09/rails-6-29.png" width="350" />
</a>
</figure>
<p>Then we explore exactly what it means to <strong>authenticate a user</strong> given their sign-in credentials.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/09/rails-6-30.png" width="500" />
</a>
</figure>
<p>Once authenticated, we <strong>use a session to identify the current user</strong> as they navigate from page to page.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/09/rails-6-31.png" width="500" />
</a>
</figure>
<p>And of course no authentication system would be complete without a way to <strong>sign out</strong>.</p>
<p>Enjoy!</p>
Rails 6 Videos Updated to Use form_withThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/09/19/rails-6-videos-updated-form-with2019-09-19T00:00:00Z2019-09-19T00:00:00Z<p>Releasing courses as early access is our way of trying to get the latest updates into your hands as quickly as possible. So while early-access courses aren’t initially 100% complete, our hope is that the early modules give you something to chew on while we incrementally finish up the remaining videos.</p>
<p><strong>Every once in a while during early access we have to go back and change something. That happened this week with the <a href="/courses/rails">Rails 6 course</a>.</strong></p>
<p>For as long as we can remember, there have been two ways to generate forms in Rails: <code>form_for</code> and <code>form_tag</code>. We’ve been teaching these two methods since rolling out the initial Rails video course in 2013, and even before that in live training sessions. Indeed, the interface for creating forms has been remarkably stable all these years.</p>
<p>At the same time, it has always been problematic to have two ways to do effectively the same thing. And so Rails has been decidedly moving towards a new <code>form_with</code> method that aims to unify the way all forms are generated. As this seems to be the future of Rails, we’ve gone back through the Rails 6 videos and made updates accordingly. It was a big effort, but we hope you’ll appreciate it.</p>
<h3 id="updated-videos">Updated Videos</h3>
<p>Now don’t worry: you don’t have to rewatch all the videos! At the end of this email you’ll find a list of videos with specific timecode ranges that have changed. You may just want to rewatch those sections. You also don’t have to use <code>form_with</code> in order to get on the Rails 6 train. Both <code>form_for</code> and <code>form_tag</code> still work as they always have. However, they’ve been soft deprecated starting in Rails 6 which means in future versions you’ll start to see deprecation warnings.</p>
<h3 id="how-is-formwith-different">How Is form_with Different?</h3>
<p>So you might be wondering at a high level how using <code>form_with</code> is different from using <code>form_for</code> and <code>form_tag</code>. Let’s look at a few examples…</p>
<p>Previously, you had two ways to create a form. If the form was for an ActiveRecord model object such as a user stored in the database, then you used <code>form_for</code>. For example:</p>
<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="cp"><%=</span> <span class="n">form_for</span><span class="p">(</span><span class="vi">@user</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">label</span> <span class="ss">:email</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">email_field</span> <span class="ss">:email</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">label</span> <span class="ss">:password</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">password_field</span> <span class="ss">:password</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">submit</span> <span class="cp">%></span>
<span class="cp"><%</span> <span class="k">end</span> <span class="cp">%></span>
</code></pre></div></div>
<p>This generates a <code>form</code> tag and yields a form builder object (<code>f</code>) to the associated block. You then call methods on that form builder object to generate form elements such as labels and input fields.</p>
<p>Sometimes, however, you need to generate a form that’s not bound to an ActiveRecord model object. In those cases, you had to use <code>form_tag</code> to generate the form. A common example is a “Sign In” form:</p>
<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="cp"><%=</span> <span class="n">form_tag</span><span class="p">(</span><span class="n">session_path</span><span class="p">)</span> <span class="k">do</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">label_tag</span> <span class="ss">:email</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">email_field_tag</span> <span class="ss">:email</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">label_tag</span> <span class="ss">:password</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">password_field_tag</span> <span class="ss">:password</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">submit_tag</span> <span class="s2">"Sign In"</span> <span class="cp">%></span>
<span class="cp"><%</span> <span class="k">end</span> <span class="cp">%></span>
</code></pre></div></div>
<p>Calling <code>form_tag</code> differs from calling <code>form_for</code> in two distinct ways: 1) you pass it a URL rather than a model object and 2) it does not yield a form builder to the associated block. As such, you have to use a different set of methods (ending in <code>_tag</code>) to generate form elements.</p>
<p>So <code>form_for</code> and <code>form_tag</code> both generate forms, but using two different coding styles. Wouldn’t it be nice if there was one uniform way in Rails to create all forms? Well, that’s the rationale behind the introduction of <code>form_with</code>.</p>
<p>Using <code>form_with</code>, if you have a model you specify it as the value of the <code>model</code> option, like so:</p>
<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="cp"><%=</span> <span class="n">form_with</span><span class="p">(</span><span class="ss">model: </span><span class="vi">@user</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">label</span> <span class="ss">:email</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">email_field</span> <span class="ss">:email</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">label</span> <span class="ss">:password</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">password_field</span> <span class="ss">:password</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">submit</span> <span class="cp">%></span>
<span class="cp"><%</span> <span class="k">end</span> <span class="cp">%></span>
</code></pre></div></div>
<p>And if you don’t have a model, you call <code>form_with</code> and pass it the <code>url</code> option with the URL the form submits to:</p>
<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="cp"><%=</span> <span class="n">form_with</span><span class="p">(</span><span class="ss">url: </span><span class="n">session_path</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">label</span> <span class="ss">:email</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">email_field</span> <span class="ss">:email</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">label</span> <span class="ss">:password</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">password_field</span> <span class="ss">:password</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">submit</span> <span class="s2">"Sign In"</span> <span class="cp">%></span>
<span class="cp"><%</span> <span class="k">end</span> <span class="cp">%></span>
</code></pre></div></div>
<p>In both cases, <code>form_with</code> yields a form builder object and you generate form elements by calling methods on that object. So the “guts” of the form code are the same regardless of whether you have a model or not. The only difference is whether you specify the <code>model</code> or the <code>url</code> option. The overall coding style is consistent.</p>
<h3 id="xhr-requests">XHR Requests</h3>
<p>Now there’s one more important thing you need to know about <code>form_with</code>. By default, a form generated using <code>form_with</code> will submit its data using an XHR (Ajax) request. Both <code>form_for</code> and <code>form_tag</code> can do this, too, but you have to set the <code>remote</code> option to <code>true</code>. With <code>form_with</code>, <code>remote: true</code> is the default.</p>
<p>Using an XHR request by default makes sense given the close relationship Rails has with Turbolinks to speed up navigating between pages. We’ll explore those benefits later on in the course when we get to the topic of Turbolinks. Until then, we think forms are easier to learn if they use the browser’s normal submit mechanism. To do that, we set the <code>local</code> option to <code>true</code>:</p>
<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="cp"><%=</span> <span class="n">form_with</span><span class="p">(</span><span class="ss">model: </span><span class="vi">@user</span><span class="p">,</span> <span class="ss">local: </span><span class="kp">true</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="cp">%></span>
...
<span class="cp"><%</span> <span class="k">end</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">form_with</span><span class="p">(</span><span class="ss">url: </span><span class="n">session_path</span><span class="p">,</span> <span class="ss">local: </span><span class="kp">true</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="cp">%></span>
...
<span class="cp"><%</span> <span class="k">end</span> <span class="cp">%></span>
</code></pre></div></div>
<p>So that’s a quick glance at the code differences. Despite having to refilm a bunch of videos, we like how <code>form_with</code> unifies the interface for generating forms. We would have preferred that <code>form_with</code> not generate a remote form by default, but that’s just our personal preference coming from a teaching perspective.</p>
<h3 id="videos-that-changed">Videos That Changed</h3>
<p>Anyway, as promised here’s a list of the changes we’ve made so you can quickly drop in to each video to see the updates:</p>
<ul>
<li>
<p>The first form we design is for editing events in <strong>Module 12 Forms Edit Part 1 at 4:36 - 10:58</strong></p>
</li>
<li>
<p>The second form is for creating new events in <strong>Module 13 Forms Create at 5:52 - 6:49</strong></p>
</li>
<li>
<p>Next we move the forms into a partial in <strong>Module 14 Partials at 2:36 - 3:57</strong></p>
</li>
<li>
<p>The registration form is next in <strong>Module 24 One-To-Many: Forms at 3:56 - 6:07</strong></p>
</li>
<li>
<p>Then it’s on to the form for creating a user account in <strong>Module 27 User Sign Up at 4:30 - 6:04</strong></p>
</li>
<li>
<p>And of course, we need a form for editing a user account in <strong>Module 28 Edit User Account at 1:22 - 3:37</strong></p>
</li>
</ul>
<p>Also, all the exercises and code have been updated to reflect <code>form_with</code>.</p>
<p>Carry on!</p>
3 Videos on User Accounts Added to Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/09/05/3-new-videos-user-accounts-rails-62019-09-05T00:00:00Z2019-09-05T00:00:00Z<p>Happy September to you! 🍁 We have three new Rails 6 videos for you today.</p>
<p>As you know, user accounts are a central part of any web application. As such, it’s important to understand exactly how they work. This is not a case where you want to simply plug in a Gem and call it a day. 😳</p>
<p>New in our <a href="/courses/rails">Rails 6 course</a> this week, we begin exploring how to design a basic <strong>account management and authentication system</strong> from scratch. You’ll come away with the confidence to roll your own custom solution or integrate (and troubleshoot) a third-party solution.</p>
<p>We start by designing a solid User model that <strong>securely stores passwords using best-practice Rails conventions</strong>.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/09/rails-6-26.png" width="600" />
</a>
</figure>
<p>Then we design a <strong>signup form</strong> so users can create accounts and a profile page that displays their account information. We also allow users to edit and delete their account. And to make the sign-up process more friendly, we also <strong>add a custom route</strong>.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/09/rails-6-27.png" width="600" />
</a>
</figure>
<p>With this <strong>complete UI for user accounts</strong> in place, the stage is set for authentication and other account-related features coming up next.</p>
<p>Enjoy!</p>
Special Launch Price 🚀 Full-Stack GraphQL Course Is Complete!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/08/29/full-stack-graphql-course-launches2019-08-29T00:00:00Z2019-08-29T00:00:00Z<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/08/full-stack-graphql-launch-price.png" width="700" />
</a>
</figure>
<p>Today we released the final videos in our <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course! If you’ve been waiting until this course was complete to snag your copy, your wait is over!</p>
<p><strong>Find out how to put together a full-stack app using Phoenix as the backend server + Absinthe for the GraphQL API + React with Apollo on the frontend.</strong></p>
<p>The full course includes:</p>
<ul>
<li><strong>4.5 hours</strong> unpacking the code of a full-stack app</li>
<li><strong>37 videos</strong> all with English subtitles</li>
<li><strong>17 animations</strong> exploring key design elements</li>
<li><strong>All the source code</strong>, of course!</li>
</ul>
<p>We’ve put hundreds of hours and everything we know about how to build full-stack GraphQL apps into this course. Our hope is you’ll feel empowered to now build your own great GraphQL apps!</p>
<h3 id="final-videos-released-today">Final Videos Released Today</h3>
<h4 id="subscribing-to-booking-changes">#32 Subscribing To Booking Changes</h4>
<p>In addition to queries and mutations, <strong>Apollo Client has excellent support for GraphQL subscriptions</strong>. Given a stream of subscription data, it’s easy to merge that data directly into the Apollo cache. We set up the client to subscribe to booking changes and update the booking calendar in near real-time whenever a booking is created or canceled.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/08/unpacked-graphql-32.png" width="400" />
</a>
</figure>
<h4 id="refetching-queries">#33 Refetching Queries</h4>
<p>Most of the time you’ll let Apollo Client cache all the query results and not think twice about it. But sometimes you need to <strong>refresh cached query results in response to a particular user action</strong>, such as creating a booking. We’ll show you how!</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/08/unpacked-graphql-33.png" width="400" />
</a>
</figure>
<h4 id="infinite-scroll-pagination">#34 Infinite Scroll Pagination</h4>
<p>Paginating query results is such a common need that Apollo Client makes it easy to do. We first modify our backend GraphQL API to <strong>support offset-based pagination</strong>. Then we tie pagination into the frontend so that getaway places can be fetched and displayed in batches.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/08/unpacked-graphql-34.png" width="400" />
</a>
</figure>
<p>Enjoy!</p>
Rails 6 Is Out, and 3 New Videos on Nested ResourcesThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/08/23/rails-6-is-out-and-3-new-videos2019-08-23T00:00:00Z2019-08-23T00:00:00Z<p>It’s official, <a href="https://weblog.rubyonrails.org/2019/8/15/Rails-6-0-final-release/" target="_blank">Rails 6 is out</a> and ready for you! 🎉</p>
<p>From DHH, the creator of Rails:</p>
<blockquote>
<p>While we took a little while longer with the final version than expected, the time was spent vetting that <strong>Rails 6 is solid</strong>. In fact, GitHub, Shopify, and Basecamp, as well as plenty of other companies and applications, have been running the pre-release version of Rails 6 for months and months in production. We might not have caught everything, but <strong>if it’s good enough for GitHub, Shopify, and Basecamp, it’s probably good enough for you too!</strong></p>
</blockquote>
<p>Here’s something else that’s official:</p>
<p>Our original Rails Level I <a href="/courses/rails">course has been entirely updated for Rails 6</a>! The videos have been re-recorded and all the workbook exercises have been rewritten! And in coming weeks we’ll release videos on the Rails Level II content starting with user account management. Managing your users’ accounts isn’t an area of your app that should be a black box!</p>
<figure>
<a href="/courses/rails">
<img src="/images/courses/rails-large.png" width="400" />
</a>
</figure>
<p><strong>This week we have 3 new videos for you wrapping up one-to-many associations with Rails 6:</strong></p>
<p>Registrations only make sense in the context of their associated event. So in Module #23, we mimic that one-to-many relationship in our routes by nesting registration resources within an event resource. This is a <strong>common design technique that you’ll definitely want to have in your arsenal!</strong></p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/08/rails-6-23.png" width="600" />
</a>
</figure>
<p>How do you <strong>design a form for a one-to-many relationship</strong> so you can create child records that are associated with their parent? Answering this in Module #24 gives us an opportunity to apply (and reinforce) everything we’ve learned so far.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/08/rails-6-24.png" width="600" />
</a>
</figure>
<p>Once you start making associations between models and collecting data, you’ll likely discover some interesting things. What’s the average star rating for a movie? What determines if it’s a cult classic? The code that answers those type of questions is part of the business logic of your domain. And <strong>knowing where to put that code is vital to designing a maintainable application</strong>. That’s the topic of Module #25.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/08/rails-6-25.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
2 New Videos on One-to-Many Associations Added To Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/08/15/2-new-videos-one-to-many-associations-rails-62019-08-15T00:00:00Z2019-08-15T00:00:00Z<p>One of the most powerful features of Rails is the ability to create relationships between models and represent those relationships in a database.</p>
<p>🎬 This week we have 2 new videos for you in our <a href="/courses/rails">Ruby on Rails 6 course</a> as we begin to design a one-to-many relationship.</p>
<p>Up to this point in the course, we’ve been focused on one resource. Now we want to let folks register for events and write reviews for movies. To do that, we’ll need to <strong>create new resources</strong> and then look at both sides of the associations.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/08/rails-6-21.png" width="500" />
</a>
</figure>
<p>Knowing the “magic” incantations for one-to-many associates isn’t nearly enough. To be really empowered, you also need to know <strong>what goes on behind the scene. We’ll show you!</strong></p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/08/rails-6-22.png" width="500" />
</a>
</figure>
<p>Enjoy!</p>
2 New Videos On Reviews and Reservations Added To Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/08/08/2-new-videos-reviews-reservations-full-stack-graphql2019-08-08T00:00:00Z2019-08-08T00:00:00Z<p>As we get deeper into August, it’s hard not to miss that back-to-school season is in full swing. 🤓 📚 And we’re ready for it!</p>
<p>We took a couple weeks off to move into our temporary new office. Now that we’re settled in, we’re primed for back-to-Studio season.</p>
<p>This week we have 2 new videos for you in our <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course. These are the last two videos before we officially launch the completed course with the final videos.</p>
<p>In <strong>module #30</strong>, we continue on with the Place page and use a mutation to create new reviews. This is very similar to other form-based mutations we’ve seen. But this time there’s an interesting twist!</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/08/unpacked-graphql-30.png" width="600" />
</a>
</figure>
<p>When a new review is created, we learn how to update the cache so that the newly-created review is dynamically added to the top of the list of reviews.</p>
<p>The Place page also lets you pick a range of dates on a calendar and book a reservation, and that’s yet another mutation we learn about in <strong>module #31</strong>.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/08/unpacked-graphql-31.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
2 New Videos Added To Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/07/18/2-new-videos-full-stack-graphql2019-07-18T00:00:00Z2019-07-18T00:00:00Z<p>As the heat of summer settles in 🏝, we start on the capstone of our <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course. Two new videos for you this week! Ahhhh…</p>
<p>First up, with authentication now in place, we’re ready to <strong>explore how to query and mutate user-specific data such as a user’s bookings</strong>. We use a query to fetch the current user’s bookings and a mutation to cancel a specific booking. And we <strong>design another higher-order component</strong> that redirects to the Sign In page if you’re not signed in.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/07/unpacked-graphql-28.png" width="600" />
</a>
</figure>
<p>The final page puts together everything we’ve learned so far! We use a query to fetch all the details for a specific getaway place, including its bookings and reviews. We use mutations to create bookings and reviews, requiring a signed-in user. And we use a subscription to update the booking calendar in near-real time.</p>
<p>We start unpacking this page by <strong>looking at the query and how it interacts with the cache</strong>.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/07/unpacked-graphql-29.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
4 New Videos On Authentication Added To Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/07/09/4-new-videos-authentication-full-stack-graphql2019-07-09T00:00:00Z2019-07-09T00:00:00Z<p>In the <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course, we’ve been dancing 🕺 around the need for authentication in the frontend app. But now we’re ready to dive into form-based mutations and caching smartly!</p>
<p>The <strong>Sign Up</strong> form is indicative of many forms used to create entities by running a GraphQL mutation. We learn how to use <strong>Apollo React’s Mutation component</strong> to run a mutation with variables bound to form data.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/07/unpacked-graphql-24.png" width="600" />
</a>
</figure>
<p>To get the current user’s info we design a <strong>React higher-order component that fetches the current user</strong>. Then we learn how to cache the current user after they’ve signed up so the UI reacts immediately.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/07/unpacked-graphql-25.png" width="600" />
</a>
</figure>
<p>After designing a <strong>Sign In</strong> form that runs a mutation and updates the cache, you’ll come away with the confidence to implement any <strong>form-based mutation</strong>.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/07/unpacked-graphql-26.png" width="600" />
</a>
</figure>
<p>For <strong>Sign Out</strong>, we dig deep into how Apollo Client’s caching works so we avoid unnecessary API requests.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/07/unpacked-graphql-27.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
3 New Videos on Validations Added To Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/07/09/3-new-videos-rails-62019-07-09T00:00:00Z2019-07-09T00:00:00Z<p>In the <a href="/courses/rails">Rails 6 course</a>, our forms currently let in bad data. Yikes! It’s high time we ensure the integrity of our application data and give notice to our users when things go right as well as when things go wrong. 💥</p>
<p>To prevent bad (invalid) data from making its way into the database, we add a variety of <strong>model validations</strong> and explore how they work in detail.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/07/rails-6-18.png" width="600" />
</a>
</figure>
<p>Now we’re ready to <strong>handle and display any validation errors</strong> when submitting form data. You’ll come away with a solid strategy for ensuring the integrity of your application’s data while providing actionable feedback in the user interface.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/07/rails-6-19.png" width="600" />
</a>
</figure>
<p>While on the topic of user feedback, we have a few cases where we need to flash a stylish message up on the page. It’s common for web apps to <strong>flash messages</strong> between requests, and so Rails makes it easy.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/07/rails-6-20.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
2 New Videos On Caching and Searching Added To Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/06/27/2-new-videos-on-caching-and-searching-full-stack-graphql2019-06-27T00:00:00Z2019-06-27T00:00:00Z<p>As we move into summertime here 🍉 we also move into the 4th hour of our <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course. Sweet!</p>
<p>This week we have 2 new videos for you!</p>
<p>Caching is difficult to do right. It’s also essential if you want your GraphQL client to be snappy. Thankfully, <strong>Apollo Client has fantastic caching right out of the box</strong>. By default, it automatically and intelligently caches all query results. We go behind the scenes to get a glimpse of the cache in action so we can take advantage of it!</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/06/unpacked-graphql-22.png" width="600" />
</a>
</figure>
<p>Also, how do you implement a front-end component that runs a search query based on what the user selects as filter criteria? <strong>Search is really common and we show you how to do it.</strong></p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/06/unpacked-graphql-23.png" width="600" />
</a>
</figure>
<p>Coming up next we’ll explore authentication in our GraphQL app and find out if you are who you say you are.</p>
2 New Videos Added To Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/06/18/2-new-videos-rails-62019-06-18T00:00:00Z2019-06-18T00:00:00Z<p>The app we’re building in our step-by-step <a href="/courses/rails">Rails 6 course</a> needs two additional features: a custom query and a new database migration. How do we do this? Find out in the two new videos this week! 🎥</p>
<h3 id="custom-queries">#16 Custom Queries</h3>
<p>How do we fetch a subset of events from the database? Thankfully, <strong>Active Record has a rich query interface</strong> that insulates us from having to write raw SQL to query our data. Master these query methods and you can slice and dice your data with ease, regardless of which database you use.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/06/rails-6-16.png" width="500" />
</a>
</figure>
<h3 id="migrations-revisited">#17 Migrations Revisited</h3>
<p>What happens when we need to add new fields to a database table? Well, it’s time for a new migration! And anytime you <strong>migrate the database</strong>, you also need to think through <strong>the ripple effects</strong>. Come along as we work through all the steps to accommodate a new migration.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/06/rails-6-17.png" width="500" />
</a>
</figure>
<p>Enjoy!</p>
3 New Videos On Apollo Client Added To Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/06/11/3-new-videos-on-apollo-client-full-stack-graphql2019-06-11T00:00:00Z2019-06-11T00:00:00Z<p>The backend app in our <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course is now complete. Yeehaw! 🤠</p>
<p>This week we <strong>begin unpacking the React app with Apollo Client</strong> on the frontend with 3 new videos for you!</p>
<p>To get our bearings and start on solid footing, we first explore how the React app is structured and organized with components and routing.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/06/unpacked-graphql-19.png" width="600" />
</a>
</figure>
<p>So how do React components get data from the GraphQL API? Well, they don’t interact with the API directly. Instead, the Apollo Client JS library acts as a very capable intermediary.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/06/unpacked-graphql-20.png" width="600" />
</a>
</figure>
<p>Then, with an Apollo Client instance linked to the GraphQL API, we learn how to use Apollo React’s Query component to fetch data from the API and render the results on the Home page.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/06/unpacked-graphql-21.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
3 New Videos Added To Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/06/06/3-new-videos-rails-62019-06-06T00:00:00Z2019-06-06T00:00:00Z<p>Last week in our <a href="/courses/rails">Rails 6 course</a> we saw that Rails has a whole bunch of conventions to help you create robust and friendly forms with minimal code.</p>
<p>This week we have 3 new videos for you, and at this point in the course, you can now <strong>confidently build a CRUD interface for any resource!</strong></p>
<p>Reinforcing what we learned about forms for editing records, we tackle creating records as we continue to implement the full range of CRUD actions using resource routes.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/06/rails-6-14a.png" width="500" />
</a>
</figure>
<p>Crafting good Rails apps isn’t just about implementing features that work as advertised. Good Rails apps also have clean, well-organized code. To that end, we learn how to use partials to structure the view layer into reusable, manageable chunks.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/06/rails-6-14b.png" width="500" />
</a>
</figure>
<p>We finish up implementing the resource routes by deleting records.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/06/rails-6-15.png" width="500" />
</a>
</figure>
<p>Enjoy!</p>
New Video On Subscriptions Added To Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/05/30/new-video-on-subscriptions-full-stack-graphql2019-05-30T00:00:00Z2019-05-30T00:00:00Z<p>In the <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course, we currently have all the queries and mutations in place. In this week’s video we cap off the API with a subscription. Drawing on the power of Phoenix channels, Absinthe provides unparalleled support for GraphQL subscriptions.</p>
<p>In <strong>module #18</strong> we add a subscription so clients can receive live updates whenever a booking is created or canceled.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/05/unpacked-graphql-18.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
2 New Videos On Forms Added To Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/05/30/2-new-videos-on-forms-rails-62019-05-30T00:00:00Z2019-05-30T00:00:00Z<p>In the <a href="/courses/rails">Rails 6 course</a>, next up we need a form to easily edit a resource’s details. Rails has a whole bunch of conventions to help you create robust and friendly forms with minimal code.</p>
<p>In <strong>module #12</strong> we unveil the “magic” as we design a form for editing records, storing submitted form data in a database, and dynamically displaying the updated data.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/05/rails-6-12.png" width="600" />
</a>
</figure>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/05/rails-6-13.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
Early Access Opens to the Rails 6 CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/05/14/early-access-open-rails-62019-05-14T00:00:00Z2019-05-14T00:00:00Z<p>Rails 6 is here: the first release candidate rolled off the track just two weeks ago. And we’ve got you covered!</p>
<p><strong>Today we’re opening early access to our updated and re-recorded <a href="/courses/rails">Rails 6 course</a> course.</strong> The first 13 videos, 90 minutes, and 11 chapters of the workbook are all ready for you! We’ll release new material incrementally as it’s ready in upcoming weeks.</p>
<figure>
<a href="/courses/rails">
<img src="/images/blog/2019/05/early-access-open-rails-6.png" width="400" />
</a>
</figure>
<p>🎉 This updated Rails 6 course is <strong>FREE</strong> to everyone who currently owns both the <a href="/courses/rails5">Rails Level I</a> and <a href="/courses/rails5-ii">Level II</a> courses. You’ll still have access to your Rails 5 courses, plus you get this new course!</p>
4 New Videos Added To Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/05/09/4-new-videos-full-stack-graphql2019-05-09T00:00:00Z2019-05-09T00:00:00Z<p>We hope you’ve found the first 13 modules helpful in our recently-released <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course!</p>
<p>Next week 🤞🏻 we’ll have news for you on our updated Ruby on Rails 6 course, but for now it’s time to crack into Absinthe mutations and API authentication with 4 new GraphQL video</p>
<p>In <strong>#14 Absinthe Mutations</strong>, we layer in mutations for creating and canceling a booking as well as writing a review.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/05/unpacked-graphql-14.png" width="600" />
</a>
</figure>
<p>But wait, only authenticated users should be able to create and cancel a booking, or write a review. So in <strong>#15 API Authentication</strong> we add two more mutations: signup and signin.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/05/unpacked-graphql-15.png" width="600" />
</a>
</figure>
<p>Then in <strong>#16 Authenticating API Requests</strong>, we add a piece of Absinthe middleware that attempts to identify the user sending API requests.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/05/unpacked-graphql-16.png" width="600" />
</a>
</figure>
<p>Finally, now that the API can identify the current user, we add a new query in <strong>#17 Current User Query</strong> to get the current user’s info, including their bookings.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/05/unpacked-graphql-17.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
3 New Videos On Dataloader Added To Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/04/23/3-new-videos-on-dataloader-full-stack-graphql2019-04-23T00:00:00Z2019-04-23T00:00:00Z<p>A special thanks to all of you who have taken advantage of early access for our <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course! Your feedback is priceless and we love hearing how the first 10 modules have been a helpful springboard for you.</p>
<p>This week we have three new videos for you all focused on Dataloader, which is the unsung hero when it comes to GraphQL query performance.</p>
<p>As <strong>#11 Intro to Dataloader begins</strong>, we have a classic N+1 query problem. So we start by giving Dataloader a whirl in IEx to understand how it works under the hood.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/04/unpacked-graphql-11.png" width="600" />
</a>
</figure>
<p>Then in <strong>#12 Optimizing Queries with Dataloader</strong> we use it to efficiently load data in batches when querying for associations. The result is less code to maintain and no risk of N+1 query problems when requesting data.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/04/unpacked-graphql-12.png" width="600" />
</a>
</figure>
<p>But wait, there’s more: Dataloader goes beyond simply loading data in batches. In <strong>#13 Dataloader Filtering and Ordering</strong> we define filtering and ordering rules for various query fields.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/04/unpacked-graphql-13.png" width="600" />
</a>
</figure>
<p>Also, we’ve added more example data to <tt>seeds.exs</tt>, so be sure to grab a new copy of the code bundle. Enjoy!</p>
Early Access Opens to the Full-Stack GraphQL CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/04/12/early-access-open-full-stack-graphql2019-04-12T00:00:00Z2019-04-12T00:00:00Z<p>Here at Pragmatic Studio HQ, we’ve received one very consistent piece of feedback these last few months: “I’m working on a full-stack app <em>right now</em> using GraphQL. Please release your course already!”</p>
<p>We heard you! Today we’re opening early access to our <a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">Unpacked: Full-Stack GraphQL</a> course. The code is 99% complete and 30% of the videos are ready for you. And we’ll release new modules incrementally as they’re ready in upcoming weeks.</p>
<figure>
<a href="/courses/unpacked-full-stack-graphql-with-absinthe-phoenix-react">
<img src="/images/blog/2019/04/early-access-open-full-stack-graphql.png" width="400" />
</a>
</figure>
<p>By rolling out this course early, we hope that you’ll benefit from exploring a full-stack GraphQL app and can use it as a springboard for creating your own app!</p>
New Tutorial: How To Setup GraphQL in a Phoenix ApplicationThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/04/10/how-to-setup-graphql-in-a-phoenix-app2019-04-10T00:00:00Z2019-04-10T00:00:00Z<p>After watching <a href="/tutorials/what-is-absinthe">last week’s video</a> on Absinthe, you may be wondering: <strong>How do I setup GraphQL in a Phoenix application?</strong></p>
<p>Wonder no more ‘cuz we’ve got you covered!</p>
<p>Whether you already have a Phoenix app in production or you’re generating a fresh Phoenix app, adding a GraphQL API is both clean and easy thanks to the Absinthe GraphQL toolkit for Elixir.</p>
<p>Starting with a newly-generated Phoenix 1.4 app, in this <a href="/tutorials/how-to-setup-graphql-in-a-phoenix-app">new tutorial</a> we walk you step-by-step through how to add a GraphQL API layer atop an Ecto data model.</p>
<figure>
<a href="/tutorials/how-to-setup-graphql-in-a-phoenix-app">
<img src="/images/blog/2019/04/how-to-setup-graphql-in-a-phoenix-app.png" width="400" />
</a>
</figure>
New Tutorial: What Is Absinthe?The Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/04/04/what-is-absinthe2019-04-04T00:00:00Z2019-04-04T00:00:00Z<p>From the previous three tutorials (<a href="/tutorials/what-is-graphql">part 1</a>, <a href="/tutorials/what-can-graphql-do">part 2</a>, <a href="/tutorials/what-does-a-graphql-api-know">part 3</a>) you now know that a GraphQL API is a special kind of API that supports queries, mutations, and subscriptions. These are defined by a schema and GraphQL clients can introspect that schema.</p>
<p><strong>So how do you build a GraphQL API?</strong></p>
<p>If you’re an Elixir developer, you use Absinthe in a Phoenix app and you’ve got yourself a robust, blazing-fast GraphQL API!</p>
<p>In the <a href="/tutorials/what-is-absinthe">final animated video</a> in our 4-part GraphQL series, we give you a quick tour of Absinthe.</p>
<figure>
<a href="/tutorials/what-is-absinthe">
<img src="/images/blog/2019/04/what-is-absinthe.png" width="400" />
</a>
</figure>
New Tutorial: What Does a GraphQL API Know?The Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/03/21/what-does-a-graphql-api-know2019-03-21T00:00:00Z2019-03-21T00:00:00Z<p>From our previous GraphQL tutorials, you now know that a GraphQL API is a special kind of API that supports queries, mutations, and subscriptions.</p>
<p><strong>So how does a GraphQL client find out what operations a GraphQL API supports?</strong></p>
<p>Well, thankfully a GraphQL API comes with a schema that defines everything that’s possible. And GraphQL clients can introspect that schema.</p>
<p>We show you how in our <a href="/tutorials/what-does-a-graphql-api-know">6-minute animated video</a>!</p>
<figure>
<a href="/tutorials/what-does-a-graphql-api-know">
<img src="/images/blog/2019/03/what-does-a-graphql-api-know.png" width="400" />
</a>
</figure>
New Tutorial: What Can GraphQL Do?The Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/02/20/what-can-graphql-do2019-02-20T00:00:00Z2019-02-20T00:00:00Z<p>In our <a href="/tutorials/what-is-graphql">previous tutorial</a> we showed you how we think of GraphQL, but we only told you part of the story! There’s much more to GraphQL.</p>
<p>So we made a second <a href="/tutorials/what-can-graphql-do">5-minute animated video</a> to show you what GraphQL can do!</p>
<figure>
<a href="/tutorials/what-can-graphql-do">
<img src="/images/blog/2019/02/what-can-graphql-do.png" width="400" />
</a>
</figure>
New Tutorial: What Is GraphQL?The Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/02/06/what-is-graphql2019-02-06T00:00:00Z2019-02-06T00:00:00Z<p>GraphQL is an expressive query language for your API that blah, blah, blah….😴</p>
<p>Indeed, our eyes glazed over every time we tried to write out a definition for you. So we decided to take a different approach!</p>
<p>We made a <a href="/tutorials/what-is-graphql">4-minute animated video</a> to show you how we think of GraphQL and its benefits.</p>
<figure>
<a href="/tutorials/what-is-graphql">
<img src="/images/blog/2019/02/what-is-graphql.png" width="400" />
</a>
</figure>
Complete Unpacked Single-Page App Course Launches!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2019/01/09/unpacked-single-page-app-course-launches2019-01-09T00:00:00Z2019-01-09T00:00:00Z<p>Today we released the final three videos in our <a href="/courses/unpacked-single-page-app-with-vue-rails">Unpacked: Single-Page App</a> course! If you’ve been waiting for this video series to be complete before buying your copy, well, your wait is over!</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/courses/unpacked-fishub-large.png" width="300" />
</a>
</figure>
<p>The full 80-minute video series includes:</p>
<ul>
<li><strong>14 videos</strong> all with English subtitles</li>
<li><strong>7 animations</strong> exploring key design elements</li>
<li><strong>All the source code</strong>, of course!</li>
</ul>
<p>We hope you all enjoy this latest video series and feel empowered to put together Vue + Rails in your own apps!</p>
<h3 id="final-videos-released-today">Final Videos Released Today</h3>
<h4 id="authentication">#11 Authentication</h4>
<p>How should the Vue app track who’s signed in and then communicate that to the API when making authenticated requests? And what about XSS attacks and CSRF? It turns out that relying on tried-and-true Rails session cookies proved to be great approach!</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2019/01/unpacked-single-page-app-11.png" width="400" />
</a>
</figure>
<h4 id="sign-in">#12 Sign In</h4>
<p>Starting with the SignIn component, we break down the progression piece by piece. We also look at using JavaScript Promises to handle varying concerns at different levels within the app.</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2019/01/unpacked-single-page-app-12.png" width="400" />
</a>
</figure>
<h4 id="authenticated-requests">#13 Authenticated Requests</h4>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2019/01/unpacked-single-page-app-13.png" width="400" />
</a>
</figure>
<p>Enjoy!</p>
3 New Videos Added To Unpacked Single-Page App CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/12/19/3-new-videos-unpacked-single-page-app2018-12-19T00:00:00Z2018-12-19T00:00:00Z<p>Last week in our <a href="/courses/unpacked-single-page-app-with-vue-rails">Unpacked: Single-Page App</a> course we began exploring how Vuex stores state in our application. <strong>This week we have 3 more videos for you!</strong> 🐟</p>
<p>First up, we realize an empty tackle box catches no fish, so we dispatch a Vuex action to add baits to the tackle box.</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2018/12/unpacked-single-page-app-8.png" width="400" />
</a>
</figure>
<p>Then we look at the second “page” of our application: the tackle box page. This page renders the items in the angler’s tackle box and, more interestingly, the catches made on those baits.</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2018/12/unpacked-single-page-app-8.png" width="400" />
</a>
</figure>
<p>By tracing the code end-to-end we see custom Vue events in action.</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2018/12/unpacked-single-page-app-10.png" width="400" />
</a>
</figure>
<p>Enjoy!</p>
2 New Videos Added To Unpacked Single-Page App CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/12/10/2-new-videos-unpacked-single-page-app2018-12-10T00:00:00Z2018-12-10T00:00:00Z<p>We hope you found the first five modules in the <a href="/courses/unpacked-single-page-app-with-vue-rails">Unpacked: Single-Page App</a> course to be helpful. Next up, we have two new videos that begin to unpack the Vuex store!</p>
<p>We’ve seen that Fishub has multiple components that share state and also update that state. So what’s the best way to handle this? In <strong>module #6 Vuex</strong>, we discuss when it makes sense to call upon Vuex and how the store keeps everything in sync.</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2018/12/unpacked-single-page-app-6.png" width="400" />
</a>
</figure>
<p>Then in <strong>module #7 End-to-End: Fetch Tackle Box Items</strong> we explore how tackle box items are requested, received, and rendered via the Vuex store.</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2018/12/unpacked-single-page-app-7.png" width="400" />
</a>
</figure>
<p>Enjoy!</p>
Early Access Opens to the Unpacked Single-Page App CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/12/04/early-access-open-unpacked-single-page-app2018-12-04T00:00:00Z2018-12-04T00:00:00Z<p>Single-page applications (SPAs) are cropping up everywhere across the landscape of modern web app development. But building a solid SPA can be tricky: the frontend JavaScript and backend API need to work in harmony.</p>
<p>So what does it take to put together a single-page app using Vue.js on the frontend and Rails as the backend API? And how would you design it in a pragmatic, straightforward way? That’s what our new video series is all about!</p>
<p><strong>Today we’re opening early access to our <a href="/courses/unpacked-single-page-app-with-vue-rails">Unpacked: Single-Page App</a> course.</strong></p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2018/12/early-access-open-single-page-app-a.png" width="400" />
</a>
</figure>
<p>The first 5 modules are available so you don’t have to wait to get unpacking. We’ll release new modules incrementally as they’re ready in upcoming weeks. By rolling out this course early, we hope that you’ll benefit from exploring a full-stack Vue.js + Rails app and can use it as a springboard for creating your own app!</p>
<p>Rails may not be in the news as much as in years past, but it’s everywhere! So even if you’re using the hottest JavaScript framework, such as Vue.js, at some point you’ll likely need to talk to a Rails app.</p>
<figure>
<a href="/courses/unpacked-single-page-app-with-vue-rails">
<img src="/images/blog/2018/12/early-access-open-single-page-app-b.png" width="600" />
</a>
</figure>
New Tutorial: The Vue CLIThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/11/19/vue-cli2018-11-19T00:00:00Z2018-11-19T00:00:00Z<figure>
<a href="/tutorials/vue-cli">
<img src="/images/blog/2018/11/vue-cli.png" width="400" />
</a>
</figure>
<p>In this <a href="/tutorials/vue-cli">10-minute free tutorial</a>, we dive into how we used the Vue Command Line Interface (CLI) to generate the initial app and serve it up during development. By walking through the generated app, you’ll feel confident about using the Vue CLI to create, build, and serve your own apps.</p>
New Tutorial: Using Rails Session Cookies for API AuthenticationThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/09/05/rails-session-cookies-for-api-authentication2018-09-05T00:00:00Z2018-09-05T00:00:00Z<p>Over the summer, we explored the good, the bad, and the ugly of designing a Vue.js front-end web application (an SPA) with a Rails API backend.</p>
<p>One of the more interesting aspects has been figuring out <strong>how to “log in” users given that the API has protected resources that require authentication</strong>.</p>
<p>The common approach is to use an API access token. But there’s a security vulnerability with that option. 😳</p>
<p>So we asked ourselves: Is there a better way?</p>
<p>Indeed there is: Rails session cookies! 🍪</p>
<p>We wrote up a <a href="/tutorials/rails-session-cookies-for-api-authentication">tutorial</a> that walks through the problem and a solution that you might find helpful if your application has similar requirements.</p>
<figure>
<a href="/tutorials/rails-session-cookies-for-api-authentication">
<img src="/images/blog/2018/09/rails-session-cookies-for-api-authentication.png" width="400" />
</a>
</figure>
<p>Enjoy!</p>
Elixir/OTP Course Now Has Subtitles!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/08/10/elixir-course-subtitles2018-08-10T00:00:00Z2018-08-10T00:00:00Z<figure>
<a href="/courses/elixir">
<img src="/images/blog/2018/08/elixir-course-subtitles.png" width="600" />
</a>
</figure>
<p>🎉 Our <a href="/tutorials/vue-cli">Elixir/OTP course</a> now has English subtitles on all 36 videos!</p>
Apple Pay Now SupportedThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/06/07/apple-pay-support2018-06-07T00:00:00Z2018-06-07T00:00:00Z<p>We now support Apple Pay so you can easily purchase courses with just a touch of your finger!</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2018/06/apple-pay-supported.png" width="600" />
</a>
</figure>
<p>Thanks for your continued support!</p>
Vue.js Frontend Added To Multi-Player Bingo CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/05/08/vue-added-to-unpacked-bingo2018-05-08T00:00:00Z2018-05-08T00:00:00Z<p>Starting today, the frontend of <a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">Unpacked: Multi-Player Bingo</a> now comes in two flavors: Elm and Vue.js. That’s right, we’ve added 4 new videos specific to Vue.js. And if you already own the course, they’re included for <strong>FREE</strong>! 🎉</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/05/unpacked-bingo-18.png" width="480" />
</a>
</figure>
<p>All the backend Elixir and Phoenix code stayed the same (as it should!). And you can now choose your own front-end adventure starting in <strong>Module 12</strong> with the friendly reliability of <strong>Elm</strong> (6 modules, ~1 hour) and/or starting in <strong>Module 18</strong> with the progressive reactivity of <strong>Vue.js</strong> (3 modules, ~30 minutes).</p>
<p>Enjoy!</p>
Complete Unpacked Multi-Player Bingo Course Launches!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/04/19/unpacked-bingo-course-launches2018-04-19T00:00:00Z2018-04-19T00:00:00Z<p>Today we released the final 4 videos in our <a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">Unpacked: Multi-Player Bingo</a> course! If you’ve been waiting for this video series to be complete before buying your copy, well, your wait is over!</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/courses/unpacked-bingo-large.png" width="300" />
</a>
</figure>
<p>The full video series includes:</p>
<ul>
<li><strong>21 videos</strong></li>
<li><strong>14 animations</strong> exploring the key design elements</li>
<li><strong>All the source code</strong>, of course!</li>
</ul>
<p>We start with the completed application and unpack it layer by layer so you understand how it all works. You’ll come away with a solid, practical reference implementation you can draw on for your own projects.</p>
<p>We hope you all enjoy this new video series and feel empowered to build your own Elixir + Phoenix + Elm apps!</p>
<h3 id="final-videos-released-today">Final Videos Released Today</h3>
<h4 id="model-design">#16 Model Design</h4>
<p>Now that the Elm app has joined the game, we turn our attention to the design of the Elm model.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/04/unpacked-bingo-16.png" width="480" />
</a>
</figure>
<h4 id="handling-messages">#17 Handling Messages</h4>
<p>Upon successfully joining the channel, our Elm app gets three Phoenix messages right off the bat. We have to be ready to swing at them all!</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/04/unpacked-bingo-17a.png" width="480" />
</a>
</figure>
<p>What happens when a square is clicked? Or when someone types in a chat message like “I’m going to win this game”. The app handles the associated Elm messages and pushes Phoenix messages down the socket to the channel.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/04/unpacked-bingo-17b.png" width="480" />
</a>
</figure>
<p>Enjoy!</p>
4 New Videos on Elm Added To Unpacked Multi-Player Bingo CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/04/12/4-new-elm-videos-unpacked-bingo2018-04-12T00:00:00Z2018-04-12T00:00:00Z<p>This week we dive into the third part of our <a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">Multi-Player Bingo</a> game: the Elm app. From how our Elm code gets compiled and kicked off to talking on Phoenix channels, we unpack it all in today’s 4 new videos!</p>
<h3 id="elm-front-end-app-overview">#12 Elm Front-End App Overview</h3>
<p>A high-level overview reveals our Elm app is comprised of two buckets of code, and a handful of dependencies.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/04/unpacked-bingo-12.png" width="450" />
</a>
</figure>
<h3 id="building-with-brunch">#13 Building With Brunch</h3>
<p>When it comes to compiling all our Elm code to JS, packaging it up with all the other JS code in our app, and then building all our assets, the Brunch tool does all the hard work.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/04/unpacked-bingo-13.png" width="450" />
</a>
</figure>
<h3 id="embedding-with-flags">#14 Embedding With Flags</h3>
<p>To kick off our Elm app, we use a dash of JavaScript to embed the app in a specific element of the page.</p>
<h3 id="sockets-and-channels">#15 Sockets and Channels</h3>
<p>It’s time to get the conversation started and discover how our Elm app talks on Phoenix channels. Ready. Set. Join!</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/04/unpacked-bingo-15.png" width="450" />
</a>
</figure>
<p>Enjoy!</p>
New Phoenix Presence Video Added To Unpacked Multi-Player Bingo CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/03/29/new-presence-video-unpacked-bingo2018-03-29T00:00:00Z2018-03-29T00:00:00Z<p>It is presently a very good time to jump into our <a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">Unpacked: Multi-Player Bingo</a> course. 😉 All of the videos “unpacking” the Phoenix app are released and ready for you!</p>
<p>Today we released the final Phoenix-specific video: <strong>#11 Who’s Playing, Presently?</strong></p>
<p>It can be tricky to track who has joined a game, who is presently playing a game, and who has left a game for a meeting with tastier donuts. Thankfully, Phoenix Presence is really clever about keeping all the players in sync.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/03/unpacked-bingo-11.png" width="500" />
</a>
</figure>
<p>Enjoy!</p>
New Phoenix Channel Video Added To Unpacked Multi-Player Bingo CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/03/22/new-channel-video-unpacked-bingo2018-03-22T00:00:00Z2018-03-22T00:00:00Z<p>It’s time to explore the juicy part of the Phoenix app in our <a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">Unpacked: Multi-Player Bingo</a> course!</p>
<p>If the leader of your meeting drops a lot of buzzwords, then you’re likely to have a fast-paced bingo game. So to keep everyone updated with near real-time updates, we rely on Phoenix Channels.</p>
<p>You’ll find two new videos in <strong>#10 Phoenix Channels</strong> that break it all down for you.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/03/unpacked-bingo-10a.png" width="500" />
</a>
</figure>
<p>There’s a channel topic for every game, and by subscribing to a topic, a web client maintains a stateful, persistent connection to the corresponding game server process.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/03/unpacked-bingo-10b.png" width="500" />
</a>
</figure>
<p>Enjoy!</p>
3 New Videos Added To Unpacked Multi-Player Bingo CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/03/15/3-new-videos-unpacked-bingo2018-03-15T00:00:00Z2018-03-15T00:00:00Z<p>We hope you found the first 6 modules helpful in the <a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">Unpacked: Multi-Player Bingo</a> course!</p>
<p><strong>It’s now time to crack open the Phoenix portion with 3 new videos:</strong></p>
<p>In <strong>#7 Phoenix Bingo Hall</strong>, we start with a quick lay of the land, discuss umbrella projects, and look at our dependencies.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/03/unpacked-bingo-7.png" width="300" />
</a>
</figure>
<p>To play the game, a player first needs to enter a name and color, which we then store in an HTTP session. <strong>#8 Player Sessions</strong> explores how the SessionController gets this job done.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/03/unpacked-bingo-8.png" width="300" />
</a>
</figure>
<p>Next, the GameController takes over. From rendering a form for selecting the game size to kicking off new game server process, <strong>#9 Spinning Up New Games</strong> breaks it all down for you.</p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/03/unpacked-bingo-9.png" width="300" />
</a>
</figure>
<p>Enjoy!</p>
Early Access Opens to the Unpacked Multi-Player Bingo CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2018/03/08/early-access-open-unpacked-bingo2018-03-08T00:00:00Z2018-03-08T00:00:00Z<p>By combining the concurrency of Elixir and real-time streaming in the Phoenix web framework, you can build <em>seriously</em> cool applications!</p>
<p>For example: How would you design and code a multi-player, real-time game using <strong>Elixir</strong> and <strong>Phoenix</strong> on the backend and <strong>Elm</strong> on the frontend? That’s what our latest video series is all about!</p>
<p><strong>Early access is now open to our <a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">Unpacked: Multi-Player Bingo</a> course.</strong></p>
<figure>
<a href="/courses/unpacked-multi-player-bingo-with-elixir-phoenix-vue-elm">
<img src="/images/blog/2018/03/early-access-open-unpacked-bingo.png" width="600" />
</a>
</figure>
<p>The first six modules are available starting today and we’ll release new modules incrementally as they’re ready in upcoming weeks. You don’t have to wait to get unpacking!</p>
Complete Elixir/OTP Course Launches!The Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/09/27/elixir-otp-course-launches2017-09-27T00:00:00Z2017-09-27T00:00:00Z<p>Today we released the final 3 modules in our <a href="/elixir">Developing With Elixir/OTP</a> course! If you’ve been waiting for this video series to be complete before buying your copy, your wait is over!</p>
<figure>
<a href="/courses/elixir">
<img src="/images/courses/elixir-large.png" width="300" />
</a>
</figure>
<p>In this course, you’ll see and experience Elixir/OTP development in action. For software developers, learning within this context of building a real application makes a huge difference! By developing a real app with real code, you’ll gain practical experience putting all the pieces together to craft applications the Elixir/OTP way.</p>
<p>The full course includes:</p>
<ul>
<li><strong>6.5 hours</strong> of step-by-step live coding</li>
<li><strong>36 videos</strong> - streamable and downloadable</li>
<li><strong>15 animations</strong> that break down advanced concepts</li>
<li><strong>56 hands-on exercises</strong> with all the solutions</li>
</ul>
<h3 id="final-videos-released-today">Final Videos Released Today</h3>
<p>The app we build throughout this course has multiple server processes that should run continuously without missing a beat. But things don’t always go according to plan! 😳 So we need to monitor the server processes and recover when trouble strikes.</p>
<p>Supervisors to the rescue!</p>
<p>In the final three course modules, <strong>discover how to design a supervision tree so apps can elegantly recover from unforeseen failures</strong>. As the last step, we’ll explore how to specialize the OTP Application behavior to then start the supervision tree!</p>
<h4 id="linking-processes">#28 Linking Processes</h4>
<p>By creating a new “Kickstarter” process and linking it to our web server process, we can monitor our server process and if necessary, kickstart it when trouble strikes.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/09/elixir-28.png" width="480" />
</a>
</figure>
<h4 id="fault-recovery-with-otp-supervisors">#29 Fault Recovery with OTP Supervisors</h4>
<p>OTP Supervisors offer unparalleled support for detecting and recovering from process failures. By designing and implementing a supervision tree, our application will elegantly recover from unforeseen failures.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/09/elixir-29.png" width="300" />
</a>
</figure>
<h4 id="final-otp-application">#30 Final OTP Application</h4>
<p>An Elixir application is a first-class OTP entity… which means what exactly? Good question! We’ll look at how an OTP application works behind the scenes, how to specialize the OTP Application behavior to start our supervision tree, and how to configure the default application environment.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/09/elixir-30.png" width="480" />
</a>
</figure>
<p>In the end, you have a complete OTP application designed the Elixir way!</p>
<p><strong>A HUGE THANKS</strong> to all of you who tweeted about his course, reviewed early drafts, and sent in suggestions! Your feedback and encouragement was instrumental in designing and completing this course.</p>
Another GenServer Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/09/20/another-genserver-module-elixir2017-09-20T00:00:00Z2017-09-20T00:00:00Z<p>Writing a new server process that performs background work on a periodic interval let’s us explore different ways to leverage all that GenServer has to offer. This week’s new <strong>module #27 Another GenServer</strong> of our <a href="/courses/elixir">Elixir/OTP course</a> shows you how!</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/09/elixir-27.png" width="600" />
</a>
</figure>
<p>Enjoy!</p>
GenServer Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/09/13/genserver-module-elixir2017-09-13T00:00:00Z2017-09-13T00:00:00Z<p>It’s now time to use Elixir’s official GenServer behavior in our application! All the work you put into the last two modules of the <a href="/courses/elixir">Elixir/OTP course</a> is absolutely going to pay off right here, right now.</p>
<p>Actually using a GenServer in this week’s new <strong>module #26 OTP GenServer</strong> is a snap because you already understand GenServer’s underlying design pattern and how it’s implemented. Besides converting our app to use a GenServer (and eliminating a bunch of code!) we also add new application-specific behavior to our GenServer.</p>
<p>Spoiler Alert: At the end of this module, GenServer will no longer feel magical. 😉</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/09/elixir-26.png" width="350" />
</a>
</figure>
<p>Enjoy!</p>
Refactor Toward GenServer Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/09/06/refactor-toward-genserver-module-elixir2017-09-06T00:00:00Z2017-09-06T00:00:00Z<p>At this point in our <a href="/courses/elixir">Elixir/OTP course</a>, we see two types of code in our client-server interaction:</p>
<ul>
<li>
<p><strong>Application-specific code</strong> that applies only to our PledgeServer process</p>
</li>
<li>
<p><strong>Common code</strong> that is needed for any server process</p>
</li>
</ul>
<p>So what happens when we move all the common code into a generic module?</p>
<p>Well, we’re not the first ones to have that idea! In fact, writing stateful server processes is so common that <strong>Elixir provides an abstraction: GenServer</strong>. GenServer is a design pattern (an OTP behavior) that helps us write server processes with greater ease.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/09/elixir-25a.png" width="500" />
</a>
</figure>
<p>In this week’s new module <strong>#25 Refactoring Toward GenServer</strong> we refactor our code toward the GenServer style and by the end, you’ll have a deep understanding of how (and why!) it works.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/09/elixir-25b.png" width="300" />
</a>
</figure>
<p>Enjoy!</p>
Stateful Server Processes Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/08/30/stateful-server-processes-module-elixir2017-08-30T00:00:00Z2017-08-30T00:00:00Z<p>So far in our <a href="/courses/elixir">Elixir/OTP course</a> we’ve been looking primarily at short-lived processes.</p>
<p>But it’s now time to turn our attention to <strong>long-running server processes that manage internal state and do asynchronous work</strong>.</p>
<p>So what kind of server process will we need? Well, we’re going to run a pledge drive in hopes of building a crocodile swamp on our wildlife refuge. 🐊 And we’ll need to cache recent pledges and run computations.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/08/elixir-24a.png" width="480" />
</a>
</figure>
<p>To do this, we’ll build up from a basic receive loop to a client API that sends synchronous and asynchronous requests to a registered server process.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/08/elixir-24b.png" width="400" />
</a>
</figure>
<p>Along the way, we’ll see how a server process preserves the integrity of its state while under load from multiple concurrent client processes.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/08/elixir-24c.png" width="480" />
</a>
</figure>
<p><strong>By writing a server process from scratch, we’ll begin to demystify the “magic” of a GenServer.</strong></p>
<p>If you already own the course, you’ll find this week’s new 4-part module in your account today: <strong>#24 Stateful Server Processes</strong>.</p>
<p>Enjoy!</p>
<p>P.S. Many thanks to Scott Thompson, Clinton De Young, and Nathan Herald for taking the time to review early drafts of our OTP and GenServer sections. Your insights and suggestions based on hard-won experience with Elixir/OTP were instrumental in the design of this course. We sincerely appreciate your feedback!</p>
Asynchronous Tasks Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/08/16/tasks-module-elixir2017-08-16T00:00:00Z2017-08-16T00:00:00Z<p>With several one-off asynchronous tasks now running and getting results at a later time, we’re starting to see a definite pattern emerging. In fact, running functions (or tasks) in a short-lived process is so common that Elixir provides <strong>a really helpful abstraction: the Task module</strong>.</p>
<p>Find out how to put Elixir’s Task module to work in your app and, more importantly, how it all works under the hood in this week’s new module <strong>#23 Asynchronous Tasks</strong> from our <a href="/courses/elixir">Elixir/OTP course</a>.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/08/elixir-23.png" width="418" />
</a>
</figure>
<p>Enjoy!</p>
Sending and Receiving Messages Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/08/09/messages-module-elixir2017-08-09T00:00:00Z2017-08-09T00:00:00Z<p>So if Elixir processes are isolated and run independently, how exactly do they communicate? Find out in today’s new module of our <a href="/courses/elixir">Elixir/OTP course</a>: <strong>#22 Sending and Receiving Messages</strong>.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/08/elixir-22a.png" width="450" />
</a>
</figure>
<p>Just like people communicate, Elixir processes communicate by sending asynchronous messages to each other. In our app, we spawn a series of API requests that run in independent processes. They then send back their results as messages to be received by the request-handling process. We also look at how to avoid synchronization points in our code.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/08/elixir-22b.png" width="450" />
</a>
</figure>
<p>P.S. While attempting to record the intro to our latest course module “on the wildlife refuge,” we quickly realized that the great outdoors aren’t as quiet as we thought. Hope you enjoy the <a href="http://pragmaticstudio.createsend1.com/t/y-l-hhpirk-l-e/" target="_blank">bloopers</a>! 😂</p>
Processes Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/07/26/processes-module-elixir2017-07-26T00:00:00Z2017-07-26T00:00:00Z<p>Concurrency and parallelism. Fault tolerance and isolation. Spawning and blocking. What does it all mean!? 🤔</p>
<p>Find out in this week’s new module <strong>#21 Concurrent, Isolated Processes</strong> from our <a href="/courses/elixir">Elixir/OTP course</a>.</p>
<p>At this point in our course, the web server can only handle one request at a time. We need a way to <strong>handle multiple requests concurrently</strong> and also isolate the failure of one request so it doesn’t affect other requests.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/07/elixir-21a.png" width="480" />
</a>
</figure>
<p><strong>Concurrent, isolated processes are what set Elixir apart from other functional languages!</strong> By spawning a process, our web server becomes not only more fault tolerant, but it can handle multiple requests concurrently.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/07/elixir-21b.png" width="480" />
</a>
</figure>
<p>We also look extensively inside the Erlang VM to see how it takes full advantage of multicore computers to achieve remarkable levels of concurrency and parallelism.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/07/elixir-21c.png" width="480" />
</a>
</figure>
<p>Enjoy!</p>
Web Sockets Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/07/19/web-sockets-module-elixir2017-07-19T00:00:00Z2017-07-19T00:00:00Z<p>It’s summertime here and <strong>picking the right tool for the job is crucial</strong> to having more time for outside fun in the sun. 😎</p>
<p>In our <a href="/courses/elixir">Elixir/OTP course</a>, it’s time to write a TCP socket server so that any HTTP client can interface with our application. That’s exactly what we do in <strong>module #20 Web Server Sockets</strong>.</p>
<p>Here’s the cool part: <strong>Elixir is compatible with all existing Erlang libraries.</strong></p>
<p><strong>Talk about a big tool to leverage!</strong> Because Elixir code is compiled into byte code that runs on the Erlang VM, you can call any Erlang library from Elixir.</p>
<p>This proves immensely helpful for the current app in our Elixir course. We have a fully-functioning HTTP request handler and we now want to write a <strong>TCP socket server</strong> so that any HTTP client can interface with our application. Erlang’s gen_tcp library to the rescue!</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/07/elixir-20.png" width="700" />
</a>
</figure>
<p>Being able to confidently transcode Erlang to Elixir is an essential skill that should be in the toolbox of every Elixir developer.</p>
<p>Enjoy!</p>
Rendering JSON Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/07/12/json-module-elixir2017-07-12T00:00:00Z2017-07-12T00:00:00Z<p>New for you this week: module <strong>#19 Rendering JSON</strong> in our <a href="/courses/elixir">Elixir/OTP course</a>.</p>
<p>Up to this point, our web server only returns HTML responses. But what if we want to <strong>render JSON in response to API requests or even handle POSTed JSON data</strong>? Often times you’ll need to use an external library that’s not built into Elixir, and this is one of those scenarios.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/07/elixir-19.png" width="350" />
</a>
</figure>
<p>Enjoy!</p>
Testing Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/06/27/testing-module-elixir2017-06-27T00:00:00Z2017-06-27T00:00:00Z<p>We have another <a href="/courses/elixir">Elixir/OTP course</a> module for you this week: <strong>#18 Test Automation</strong>.</p>
<p>Currently in our web server app, we don’t have any automated tests. Rather we’re visually “testing” the HTTP responses every time we run the app. But it’s time to automate that with ExUnit tests!</p>
<p>In this module we look at two different ways to write unit tests along with various ways to run tests in Elixir. By the end we’ll have green dots across the board!</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/06/elixir-18.png" width="400" />
</a>
</figure>
<p>Enjoy!</p>
Phoenix Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/06/20/phoenix-module-elixir2017-06-20T00:00:00Z2017-06-20T00:00:00Z<p>Now’s a great time to jump into our <a href="/courses/elixir">Elixir/OTP course</a>, especially if you’re interested in becoming proficient with Phoenix! If you already own the course, you’ll find a hot new module in your account today: <strong>A Peek at Phoenix</strong>.</p>
<p>Learning Elixir before Phoenix is a bit like learning a new language before an international trip. In order to hit the ground running, you pick up a language course, learn some common words and phrases, and practice them a bit beforehand. Then when you turn up at your destination, some of the sights and sounds feel familiar and you’re ready to explore with confidence!</p>
<p>That’s precisely one of the goals of this course: to save you time, frustration, and the perils of coding by coincidence in Phoenix by learning all the essentials of developing Elixir apps upfront.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/06/elixir-17.png" width="600" />
</a>
</figure>
<p><strong>By building a web server in Elixir, you’ll feel more comfortable and confident with Phoenix apps.</strong></p>
<p>Indeed, building even an elementary HTTP web server from scratch with Elixir, as we’ve done in this course, reveals many similarities with an out-of-the-box Phoenix app. Who would have guessed that?! 😉 Dare we say Phoenix now feels less like a foreign and fiery land.</p>
<p>Enjoy!</p>
Comprehensions Module Added To Elixir/OTP CourseThe Pragmatic Studiohttps://pragmaticstudio.com/blog/2017/06/14/comprehensions-module-elixir2017-06-14T00:00:00Z2017-06-14T00:00:00Z<p>Just for you, we have another <a href="/courses/elixir">Elixir/OTP course</a> module this week: <strong>#16 Comprehensions</strong>.</p>
<p>In our web server app, we’re currently generating HTML inside the controller. But it’s time to change that up!</p>
<p>We’ll <strong>dynamically generate content by rending template files</strong>. Similar to other web frameworks, these new templates will have a <strong>mix of both HTML and Elixir code</strong>.</p>
<p>To do so, we’ll use comprehensions to “loop” through collections of data and generate HTML in a way that keeps the template code nice and succinct.</p>
<figure>
<a href="/courses/elixir">
<img src="/images/blog/2017/06/elixir-16.png" width="450" />
</a>
</figure>
<p>Enjoy!</p>