Skip to content

Announcing September JavaScript Marathon - Free, online training!

Announcing September JavaScript Marathon - Free, online training!

JavaScript Marathon - 3 Part Series

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

Join us September 23rd, 2020 for our next JavaScript Marathon!

JavaScript Marathon is a full day of free, online courses on Angular, React, Vue, RxJS, Web Performance, and more. Come learn about some of the leading web development technologies, and concepts!

Stay for one training, or stick around for the whole day! No two sessions will be the same!


React Native in 60 Minutes - Introduction to Creating Your First Hybrid Native Application

Featuring Rob Ocel @ 11:00am - 12:00pm EDT

So, you know React, and you want to build a mobile application - how do you get started? In this training, we'll discuss the architecture of React Native and how it differs from competing approaches such as Progressive Web Applications, Ionic Capacitor, and Apache Cordova. Then, we'll make a basic application from scratch that uses data from remote APIs and device sensors, and we'll show how to test and debug the application on your device and in simulators.


Using Angular Libraries in an Nx Monorepo

Featuring Patricio Vargas @ 12:30pm - 1:30pm EDT

Learn how to use Angular libraries and share code between multiple enterprise applications in your current or your future monorepo project using Nx by the Nrwl team.


JavaScript Animations with GreenSock

Featuring Christina Gorton @ 2:00pm - 3:00pm EDT

Have you ever been to a website and wondered "Whoa, how did they do that?" In this session you will learn how to get started creating fun, interesting, and complex animations that delight users with the GreenSock animation library.


Type-Safe Databases with Prisma

Featuring Ryan Chenkie @ 3:30pm - 4:30pm EDT

TypeScript is seeing huge adoption in all kinds of settings, from enterprises to open source projects to indie side projects. The promise of type safety via TypeScript is compelling: it allows you to catch a whole class of bugs before you even deploy your code. While there's a lot of focus on making your front-end and backend code type-safe, not as much focus is put on applying the same to your database access. That's where Prisma comes in. Prisma is a database toolkit that allows you to build type-safe databases with ease. It gives you a fully typed database client which means you get type hints, autocompletion, and you are prevented from accessing your database in an invalid way. In this session, we'll build a TypeScript node API that uses Prisma for database access. We'll see how Prisma can be used to give you confidence in how you access your data and how you can be more productive by using features such as the Prisma Schema Language, migrations, and more.


Javascript-free Websites with .NET Blazor WebAssembly

Featuring Heather Downing @ 5:00pm - 6:00pm EDT

Curious about the development experience of building front-end with C#? Blazor WebAssembly makes it possible to replace all of your Javascript completely - even in the front end! Join us as we build a secure SPA in .NET and discover the tricks of debugging and the trade-offs of the server-side version of Blazor.

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

You might also like

Incremental Hydration in Angular cover image

Incremental Hydration in Angular

Incremental Hydration in Angular Some time ago, I wrote a post about SSR finally becoming a first-class citizen in Angular. It turns out that the Angular team really treats SSR as a priority, and they have been working tirelessly to make SSR even better. As the previous blog post mentioned, full-page hydration was launched in Angular 16 and made stable in Angular 17, providing a great way to improve your Core Web Vitals. Another feature aimed to help you improve your INP and other Core Web Vitals was introduced in Angular 17: deferrable views. Using the @defer blocks allows you to reduce the initial bundle size and defer the loading of heavy components based on certain triggers, such as the section entering the viewport. Then, in September 2024, the smart folks at Angular figured out that they could build upon those two features, allowing you to mark parts of your application to be server-rendered dehydrated and then hydrate them incrementally when needed - hence incremental hydration. I’m sure you know what hydration is. In short, the server sends fully formed HTML to the client, ensuring that the user sees meaningful content as quickly as possible and once JavaScript is loaded on the client side, the framework will reconcile the rendered DOM with component logic, event handlers, and state - effectively hydrating the server-rendered content. But what exactly does "dehydrated" mean, you might ask? Here's what will happen when you mark a part of your application to be incrementally hydrated: 1. Server-Side Rendering (SSR): The content marked for incremental hydration is rendered on the server. 2. Skipped During Client-Side Bootstrapping: The dehydrated content is not initially hydrated or bootstrapped on the client, reducing initial load time. 3. Dehydrated State: The code for the dehydrated components is excluded from the initial client-side bundle, optimizing performance. 4. Hydration Triggers: The application listens for specified hydration conditions (e.g., on interaction, on viewport), defined with a hydrate trigger in the @defer block. 5. On-Demand Hydration: Once the hydration conditions are met, Angular downloads the necessary code and hydrates the components, allowing them to become interactive without layout shifts. How to Use Incremental Hydration Thanks to Mark Thompson, who recently hosted a feature showcase on incremental hydration, we can show some code. The first step is to enable incremental hydration in your Angular application's appConfig using the provideClientHydration provider function: ` Then, you can mark the components you want to be incrementally hydrated using the @defer block with a hydrate trigger: ` And that's it! You now have a component that will be server-rendered dehydrated and hydrated incrementally when it becomes visible to the user. But what if you want to hydrate the component on interaction or some other trigger? Or maybe you don't want to hydrate the component at all? The same triggers already supported in @defer blocks are available for hydration: - idle: Hydrate once the browser reaches an idle state. - viewport: Hydrate once the component enters the viewport. - interaction: Hydrate once the user interacts with the component through click or keydown triggers. - hover: Hydrate once the user hovers over the component. - immediate: Hydrate immediately when the component is rendered. - timer: Hydrate after a specified time delay. - when: Hydrate when a provided conditional expression is met. And on top of that, there's a new trigger available for hydration: - never: When used, the component will remain static and not hydrated. The never trigger is handy when you want to exclude a component from hydration altogether, making it a completely static part of the page. Personally, I'm very excited about this feature and can't wait to try it out. How about you?...

Next.js + MongoDB Connection Storming cover image

Next.js + MongoDB Connection Storming

Building a Next.js application connected to MongoDB can feel like a match made in heaven. MongoDB stores all of its data as JSON objects, which don’t require transformation into JavaScript objects like relational SQL data does. However, when deploying your application to a serverless production environment such as Vercel, it is crucial to manage your database connections properly. If you encounter errors like these, you may be experiencing Connection Storming: * MongoServerSelectionError: connect ECONNREFUSED <IP_ADDRESS>:<PORT> * MongoNetworkError: failed to connect to server [<hostname>:<port>] on first connect * MongoTimeoutError: Server selection timed out after <x> ms * MongoTopologyClosedError: Topology is closed, please connect * Mongo Atlas: Connections % of configured limit has gone above 80 Connection storming occurs when your application has to mount a connection to Mongo for every serverless function or API endpoint call. Vercel executes your application’s code in a highly concurrent and isolated fashion. So, if you create new database connections on each request, your app might quickly exceed the connection limit of your database. We can leverage Vercel’s fluid compute model to keep our database connection objects warm across function invocations. Traditional serverless architecture was designed for quick, stateless web app transactions. Now, especially with the rise of LLM-oriented applications built with Next.js, interactions with applications are becoming more sequential. We just need to ensure that we assign our MongoDB connection to a global variable. Protip: Use global variables Vercel’s fluid compute model means all memory, including global constants like a MongoDB client, stays initialized between requests as long as the instance remains active. By assigning your MongoDB client to a global constant, you avoid redundant setup work and reduce the overhead of cold starts. This enables a more efficient approach to reusing connections for your application’s MongoDB client. The example below demonstrates how to retrieve an array of users from the users collection in MongoDB and either return them through an API request to /api/users or render them as an HTML list at the /users route. To support this, we initialize a global clientPromise variable that maintains the MongoDB connection across warm serverless executions, avoiding re-initialization on every request. ` Using this database connection in your API route code is easy: ` You can also use this database connection in your server-side rendered React components. ` In serverless environments like Vercel, managing database connections efficiently is key to avoiding connection storming. By reusing global variables and understanding the serverless execution model, you can ensure your Next.js app remains stable and performant....

A Breakdown of RxJS 7.0 Performance Improvements cover image

A Breakdown of RxJS 7.0 Performance Improvements

It’s official. RxJS 7.0 has been deemed stable and is now available in its beta form. The core team, committed to maintaining a dependable and adaptable reactive programming tool, has built this new release to improve many aspects of developer experience without triggering changing breaks to existing code. Through a partnership with Google, the RxJS core team was able to test its latest release by integrating the library into the Google 3 monorepository. In doing so, they ran RxJs against thousands of build targets, and across countless applications, to identify where code breaks were happening, and what could be done to ensure stronger stability. Updated Typing RxJS 7.0 is written in Typescript 3.8, which allows users to leverage all of Typescript’s latest features. For example, RxJS’ typing inference capacity, especially with respect to how the library handles generics, has significantly improved. Previous versions struggled to type larger rests of arguments, with prior upper bound limits not usually exceeding 8 or 9 values. These limitations, however, have been removed, allowing developers to pass an infinite number of values with one call. The team was also able to fix many antiquated types that did not reflect the runtime behavior of actual APIs. As a result, several Observables, including *'toPromise()'*, have been deprecated in order to mitigate the challenges of legacy behavior without significantly impacting existing code. New Features animationFrames(): an Observable that returns the milliseconds elapsed since the start of the Observable, which is especially useful for coding animation, and replaces previous methods of incrementing numbers. lastValueFrom() and firstValueFrom(): Observables that return the last and first values in a promise, respectfully. They improve upon *‘toPromise()’* by returning an ‘EmptyError’ when passing promises without values, and giving users more flexibility when selecting the values they want returned. AsyncIterable support: Any areas of code that previously accepted a Promise, or an Observable, now also accept AsyncIterables. rxjs-for-await: a separate library which supports async-await for-await loops via AsyncIterables. *'retry({resetOnSuccess: true})'*: In 6.0, if you had a source that errored with, for example, a retry count valued at 5, it would only error a total of 5 times, no matter how many successful messages it had passed. With *'retry({resetOnSuccess: true})'*, the retry count value will reset every time a successful message is passed. TimeStamp: an interface with a *‘now()’* method that returns a number. Name Changes: In order to create fewer collisions between four legacy operators, and creation methods with the same name... *'zip(other$)'* is now *'zipWith(other$)'*. *'combineLatest(a$, b$)'* is now *'combineLatestWith(a$, b$)'*. *'merge(partner$)'* is now 'mergeWith(partner$)'. *'concat(ender$)'* is now *'concatWith(ender$)'*. Deprecations In 7.0, no critical elements have been removed from the library, but several features have been deprecated. These include: ResultSelectors, which have been deprecated since 5.0. The process of passing scheduler arguments through functions such as ‘of()’ or ‘range()’ has been deprecated, and should be replaced by using ‘scheduled()’ or ‘observeOn()’. This has been done in order to remove scheduling logic from operators that don’t need it. Some subscription signatures will be deprecated. With this newest release, subscriptions should only be called with a single function, or a partial or complete Observable. The same will also go for tap signatures. This will simplify the development process and help eventually make the library more lean with future releases. Functions that pull in schedulers are now deprecated as of this release in order to prepare users for the eventual phase-out of passing schedulers to certain functions. Looking Forward to 7.1 and Beyond In order to support future changes to the library, the RxJS team will begin introducing ESLint transformations. These updates will help developers remove deprecated code, such as APIs, from their applications, and prepare users for future, major releases as the library becomes faster and leaner. However, Ben Lesh, RxJS core team lead, ensures that no breaking changes will be scheduled until version 9.0 at the earliest. How You Can Contribute The RxJS core team welcomes enthusiastic RxJS experts to help contribute to refining version 7’s future updates. Those experienced with ESLint transformations, or who want to update documentation are welcome to contribute to this open-source library. And of course, the RxJS team relies on the amazing work of authors, bloggers, content creators, and those working in developer relations, to share insights into the library with the development community. If you’re just getting started with RxJS, check out this fantastic “1 Hour to Learn RxJS” tutorial by Ben Lesh from This Dot Labs' Javascript Marathon, where you can learn about Observables and operators, including how to build an Observable from scratch!...

Making AI Deliver: From Pilots to Measurable Business Impact cover image

Making AI Deliver: From Pilots to Measurable Business Impact

A lot of organizations have experimented with AI, but far fewer are seeing real business results. At the Leadership Exchange, this panel focused on what it actually takes to move beyond experimentation and turn AI into measurable ROI. Over the past few years, many organizations have experimented with AI, but the challenge today is translating experimentation into measurable business value. Moderated by Tracy Lee, CEO at This Dot Labs, panelists featured Dorren Schmitt, Vice President IT Strategy & Innovation at Allen Media Group, Greg Geodakyan, CTO at Client Command, and Elliott Fouts, CAIO & CTO at This Dot Labs. Panelists discussed how companies are moving from early AI experiments to initiatives that deliver real results. They began by examining how experimentation has evolved over the past year. While many organizations did not fully utilize AI experimentation budgets in 2025, 2026 is showing a shift toward more intentional investment. Structured budgets and clearly defined frameworks are enabling companies to explore AI strategically and identify initiatives with high potential impact. The conversation then turned to alignment and ROI. Panelists highlighted the importance of connecting AI projects to corporate strategy and leadership priorities. Ensuring that AI initiatives translate into operational efficiency, productivity gains, and measurable business impact is essential. Companies that successfully align AI efforts with organizational goals are better equipped to demonstrate tangible outcomes from their investments. Moving from pilots and proofs of concept to production was another major focus. Governance, prioritization, and workflow integration were cited as essential for scaling AI initiatives. One panelist shared that out of nine proofs of concept, eight successfully launched, resulting in improvements in quality and operational efficiency. Panelists also explored the future of AI within organizations, including the potential for agentic workflows and reduced human-in-the-loop processes. New capabilities are emerging that extend beyond coding tasks, reshaping how teams collaborate and how work is structured across departments. Key Takeaways - Structured experimentation and defined budgets allow organizations to explore AI strategically and safely. - Alignment with business priorities is essential for translating AI capabilities into measurable outcomes. - Governance and workflow integration are critical to moving AI initiatives from pilot stages to production deployment. Successfully leveraging AI requires a balance between experimentation, strategic alignment, and operational discipline. Organizations that approach AI as a structured, measurable initiative can capture meaningful results and unlock new opportunities for innovation. Curious how your organization can move from AI experimentation to real impact? Let’s talk. Reach out to continue the conversation or join us at an upcoming Leadership Exchange. Tracy can be reached at tlee@thisdot.co....

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co