• Skip to main content
  • Skip to footer

InRhythm

Your partners in accelerated digital transformation

  • Who We Are
  • Our Work
  • Practices & Products
  • Learning & Growth
  • Culture & Careers
  • Blog
  • Contact Us

Code Lounge

May 30 2023

How To Build Full Stack Applications In AWS Amplify

Based on a Lightning Talk by: Nikolai Tarasov, Senior iOS Engineer @ InRhythm on May 18th, 2023

Overview

AWS Amplify is a comprehensive development platform offered by Amazon Web Services (AWS) that simplifies the process of building web and mobile applications. It provides developers with a set of tools, services, and libraries that streamline the development workflow and enable rapid iteration.

In Nikolai Tarasov’s Lightning Talk session, we will explore the key features of AWS Amplify and discuss its advantages in building modern applications:

  • Overview
  • What Is AWS Amplify?
  • Key Features Of AWS Amplify 
  • Advantages Of AWS Amplify
  • Closing Thoughts

What Is AWS Amplify?

AWS Amplify is an open-source framework that enables developers to build scalable and secure applications with ease. It abstracts away the complexities of backend infrastructure setup, allowing developers to focus on building features and delivering value to end-users. Amplify supports popular frontend frameworks such as React, Angular, and Vue.js, making it accessible to a wide range of developers.

Key Features Of AWS Amplify

  • Authentication And Authorization

Amplify provides a simple and secure way to add user authentication and authorization to your applications. It integrates with popular identity providers like Amazon Cognito, allowing you to easily handle user sign-up, sign-in, and password recovery flows. Amplify also provides fine-grained access control and role-based permissions, ensuring that only authorized users can access specific resources within your application.

  • Data Storage And APIs

With Amplify, you can easily integrate your application with various data storage options such as Amazon DynamoDB, Amazon Aurora, or Amazon S3. Amplify’s DataStore API simplifies data synchronization between your frontend and backend, providing real-time updates and offline capabilities. It also supports GraphQL and REST APIs, making it flexible to work with different data models and query patterns.

  • Serverless Functions

AWS Amplify enables you to write serverless functions using AWS Lambda. These functions can be triggered by events and integrated seamlessly into your application’s backend. Amplify also provides built-in support for common use cases such as file uploads, image transformations, and sending notifications. With serverless functions, you can extend your application’s functionality without managing traditional server infrastructure.

  • Hosting And Deployment

Amplify simplifies the process of hosting and deploying your applications. It provides a managed hosting service that automatically provisions and configures the necessary infrastructure to serve your frontend assets. Amplify seamlessly integrates with popular Git-based workflows, allowing you to deploy your application with a simple push to your preferred Git repository.

Advantages Of AWS Amplify

  • Rapid Development And Iteration

AWS Amplify accelerates the development process by abstracting away the complexities of backend infrastructure and providing a streamlined workflow. It enables developers to focus on building features and delivering value to end-users without getting caught up in infrastructure management. The ease of integration with popular frontend frameworks further speeds up development time.

  • Scalability And Security

By leveraging AWS services such as Amazon Cognito, AWS Lambda, and DynamoDB, Amplify provides a scalable and secure foundation for your applications. AWS’s robust infrastructure ensures that your application can handle increased traffic and demand. Amplify’s built-in security features, such as user authentication and fine-grained access control, help protect your application and data.

Closing Thoughts

AWS Amplify simplifies the process of building web and mobile applications by abstracting away the complexities of backend infrastructure. It offers a comprehensive set of features, including authentication, data storage, serverless functions, and hosting, that enable developers to build scalable and secure applications with ease. By leveraging AWS services and integrating seamlessly with popular frontend frameworks, Amplify provides a streamlined development workflow and facilitates rapid iteration.

Written by Kaela Coppinger · Categorized: Code Lounge, Learning and Development, Product Development · Tagged: Application Development, AWS, best practices, Full Stack Apps, iOS Engineering, learning and growth, Mobile Development

Apr 20 2023

Closures Vs. Combine Vs. Async Await

Based on a Lightning Talk by: Joshua Buchanan, Lead iOS Engineer @ InRhythm on March 28th, 2023 as part of the Propel Spring Quarterly Summit 2023

Author: Mike Adams, Senior Technical Writer @ InRhythm

Introduction

This image has an empty alt attribute; its file name is IR-Spring-Summit-ZOOM-Bg_iOS-1024x576.jpg
Design Credit: Joel Colletti, Lead UI/UX Designer @ InRhythm

There are three methods of asynchronous coding in Swift: Closures (i.e. completion handlers), Combine, and Async/Await. 

Closures are a fundamental feature of Swift that allow developers to define self-contained blocks of functionality, while Combine provides a modern way to handle asynchronous events and data streams. Async/Await is a new feature that makes it easier to write asynchronous code that looks and feels like synchronous code, improving the readability and maintainability of Swift code.

  • Closures – Introduced in Swift 2.0, WWDC 2015
  • Combine – iOS 13 and macOS Catalina in 2019
  • Async/Await – Swift 5.5 WWDC 2021

Asynchronous Coding Methods

Closures

In Swift programming, closures are a powerful and versatile feature that allow you to capture and store functionality for later use. A closure is a self-contained block of code that you can pass around and execute at a later time, similar to a function or method.

A common use case for closures is handling asynchronous operations, such as network requests or animations. Defining a closure that executes when the operation completes helps you to keep your code organized and avoid callback functions.

You can use closures in Swift in different ways:

  • As a function argument: Pass the closure as a function argument to define a custom behavior tailored to a specific use case.
  • As a function return value: As the return value of a function, you can create functions that generate other functions.
  • As a variable: You can assign a closure to a variable for later use.

Closures can capture and retain references to values outside of their own scope which allows you to define closures that can access and modify variables defined outside of their own function or method. 

Combine

Combine is a powerful framework that allows developers to handle asynchronous events and data streams in a more intuitive and functional way. The Combine framework provides a declarative way to define and manipulate data streams using a set of operators that can transform, filter, and combine data in various ways.

Key use cases for the Combine framework include:

  1. Handling asynchronous events: Combine allows developers to handle asynchronous events, such as network requests or user input, in a more elegant and concise way than traditional callback-based APIs
  2. Managing data streams: Combine provides a unified way to manage data streams from various sources, such as user input, network requests, and local storage
  3. Composing reactive UI: Combine can be used to create reactive UI, where the UI updates automatically in response to changes in the underlying data
  4. Testing: Combine’s declarative syntax makes it easy to write unit tests for asynchronous code

The key building blocks of Combine are publishers and subscribers. Publishers are objects that emit a stream of values over time, while subscribers consume these values and perform some action in response. Publishers can be transformed, combined, and filtered using various operators to create complex data pipelines.

In summary, the Combine framework provides a powerful way to handle asynchronous events and data streams in Swift programming.

Async/Await

Async/Await provides a more intuitive and concise way to write asynchronous code. With Async/Await, developers can write asynchronous code that looks and feels like synchronous code, which makes it easier to read, write, and maintain.

Previously, developers used callbacks or closures to handle the results of asynchronous operations which often lead to complex and difficult-to-read code, as well as potential issues with callback hell and race conditions.

With Async/Await, developers can use familiar keywords like Await and Async to write asynchronous code, which allows them to pause the execution of a function until a result is available, without blocking the main thread. This makes it easier to write code that is both asynchronous and easy to understand.

For example, this code uses Async/Await to perform a network request:

func fetchUser() async throws -> User {
    let url = URL(string: "https://example.com/user")!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

In the example, fetchUser() function is marked as Async, indicating that it is an asynchronous function. Inside the function, the await keyword is used to wait for the result of the network request, without blocking the main thread. The result is then returned as a User object.

Overall, Async/Await is a powerful new feature that makes it easier to write asynchronous code in Swift, while also improving readability and maintainability.

Comparison

Features

Note that while Closures and Combine are both used for handling asynchronous operations, they operate at different levels of abstraction. Closures are used for defining code blocks with captured values, whereas Combine is a reactive programming framework that provides a unified way to manage asynchronous data streams. Async/Await, on the other hand, is a language-level feature that simplifies the process of writing asynchronous code by allowing developers to write asynchronous code that looks and feels like synchronous code.

Feature/
Item
ClosuresCombineAsync/Await
IntroductionIntroduced in Swift 2.0 (2015)Introduced in iOS 13 and macOS CatalinaIntroduced in Swift 5.5 (2021)
PurposeDefine code blocks with captured valuesReactive programming frameworkSimplify asynchronous programming
Syntax{ (parameters) -> ReturnType in }Publisher, Subscriber,operatorasync, await
BenefitsSimplify code, increase readability,“it’s the way we’ve always done it”Manage asynchronous data streams. Pub/Sub works without much effort. Once subscribed, the “watcher” always sees the message.Very simple to code.Write asynchronous code that looks synchronous.Powerful parallelization.Less complex code.Better device utilization (additional CPU cores, etc.).More similar to other modern languages.
ShortcomingsEasy to miss “closing a loop.”Difficult to scaleDifficult to debugApple’s first try at an async coding paradigm.The developer is responsible for coding the publishers / subscribers and ensuring that the messages are published.Difficult to use in conjunction with Closures and Async/Await.For Swift Concurrency feature completeness, the minimum deployment target is iOS 15+.Though supported from iOS13+, APIs were  unavailable until iOS15.Not foolproof.Apple’s direction.
Used forEvent handlers, completion blocksAsynchronous data handling, UI bindingNetwork requests, file I/O, async operations
ConcurrencyCan run on any thread, but can cause race conditionsConcurrent data handlingNon-blocking, can run concurrently without blocking the main thread
Error handlingUses try, catch, throwUses sink, catch, replaceErrorUses try, catch, async let, throws
CompatibilityAvailable in all versions of SwiftAvailable in iOS 13+ and macOS Catalina+Available in Swift 5.5+

Side-By-Side Code Function Definition

ClosureCombineAsync/Await


The Closure example code is fairly complex and a developer would need to examine the entire code block to be certain of its operation.

In the Combine block, the code is slightly less complex. The addition of .map, .decode, and .mapError help make it more understandable.

In the Async/Await code block, not only is there less code, it is also easier to understand what the code does: Set the path, create the request, make the call, and send the data back.

The code is still doing all of the “heavy lifting” for asynchronous coding, but it doesn’t LOOK as though it is doing the heavy lifting.

Side-By-Side Function Usage

ClosureCombineAsync/Await

The comparison of the three approaches really becomes clear when you look at the synchronizing calls inside of the same function.

As you can see, the result of the first call (i.e. getting a list of food by name) must come back to complete the second call (i.e. getting a list of foods that have the same “category” as the initial result).

Managing the response from the initial call is rather difficult, especially if we need to obtain sensible information about an error when something does go wrong. That difficulty only increases when we become reliant not only on a successful response, but also rely on the data as a result of that second response to power the second request.

Resources

  • Combine
    • Apple Combine:  https://developer.apple.com/documentation/combine
    • Getting Started with Combine: https://www.vadimbulavin.com/swift-combine-framework-tutorial-getting-started/
    • Is Combine Dead? https://remotion.com/blog/is-swift-combine-dead
    • Lightning Talk: Swift Combine https://youtu.be/6AB_3oFWvBg
  • Async Await
    • “Getting Started with Swift Concurrency” https://developer.apple.com/news/?id=o140tv24
    • “Async Await in Swift explained with code examples” https://www.avanderlee.com/swift/async-await/

Written by Mike Adams · Categorized: Code Lounge, InRhythmU, Learning and Development, Software Engineering · Tagged: Async/Await, Closures, Combine, INRHYTHMU, learning and growth, software engineering, Swift

Apr 12 2023

Structured Concurrency In Swift

Based on a Lightning Talk by: Joshua Buchanan, Lead iOS Engineer @ InRhythm on March 28th, 2023 as part of the Propel Spring Quarterly Summit 2023

Author: Mike Adams, Senior Technical Writer @ InRhythm

Swift Concurrency

Design Credit: Joel Colletti, Lead UI/UX Designer @ InRhythm

Concurrency is a task-based system that allows developers to take full advantage of the “await” portion of the Async/Await keywords to perform concurrent task execution. An Async/Await task waits until its process finishes before continuing.

Async/Await lets you take advantage of parallelization to make full use of all the available CPU cores to give your users the best user experience. 

Swift Concurrency includes, Async/Await, Tasks, and Task Groups. As you read “Async/Await,” assume that it means the entirety of Swift Concurrency and not simply, Async/Await.

Here are the keywords and concepts we’ll use in discussing Structured Concurrency:

  • Task – That portion of the concurrency framework that creates the concurrent environment. It can throw errors and return values
  • Child Task – A task generated and managed by a Parent Task.The Parent is responsible for task execution
  • Cancellation – In Swift, you can cancel or stop any task from completing. Unlike Combine, structured concurrency does not require a strong reference to emit values from the publisher (i.e., the Task) and continue to run even if you remove references to the publisher. If you don’t want the task to run, you must either cancel or stop it
  • Priorities – Structured Concurrency’s Task Priorities are very similar to Apple’s Quality of Service system. Task Priorities include:
    • High
    • Background
    • Low
    • Medium
    • userInitiated
    • Utility

When using Structured Concurrency in your code, remember that while priority setting in your code tells the system which tasks are most important, those priorities are only a suggestion, not a mandate. 

Async/Await

Async/Await provides the Structured Concurrency that removes the necessity of manually propagating errors and managing cancellation, as well as any other types of concurrency issues (e.g., race conditions). It makes program logic simpler to follow as the methods execute linearly rather than with the back and forth required when using completion handlers. 

Structured concurrency also improves performance and allows for cleaner, more readable code with more precise error handling. In structured concurrency, long-running tasks are self-managing in regard to resources, error propagation, or any concurrency issues. 

Async/Await was first popularized in 2012 via the C# programming language. Between 2012 and 2020, other languages began adopting Async/Await, including but not limited to:

  • Python / Typescript in 2015
  • Kotlin in 2018
  • Rust in 2019
  • C++ in 2020
  • Swift in 2021

Tasks

Although Tasks appear very basic, behind the scenes there is a great deal happening. 

The Task keyword tells the compiler that the code inside the brackets must run in its own area using different rules than the rest of the application. This is the beginning of writing concurrent code in Swift.

In Swift, Tasks check if they were cancelled at appropriate times during execution. If cancelled, the Task begins whatever processing is necessary to cease execution and then responds to the cancellation. Depending on the code, the response could be returning partially finished work, returning an empty collection (or nil), or throwing a cancellation error.

Task Example

The load function shown below displays all the parts of a concurrent function coded as a task.

Child Tasks

Child Tasks are bound to a Parent Task and inherit the Parent Task’s Priority. Parent Tasks can have multiple Child Tasks and a Child Task can be a Parent Task to other Child Tasks.

While Parent Tasks can cancel a Child Task, a Child Task can not cancel their Parent task. Child Tasks begin whatever process is necessary for them to halt once their Parent Task is cancelled. All Child Tasks must finish before the Parent Task can be completed.

Cancellations

Unlike Combine, Tasks in Structure Concurrency will continue to run even when there are no Subscribers. Tasks run until they are completed or until you cancel them in code or programmatically. Cancellations are not determined by strong reference.

Tasks “know” whether they’ve been canceled and you can explicitly cancel a Task. You can also use the Task.checkCancellation() call to check if a Task was cancelled.

There are a number ways to programmatically cancel a Task including:

  • Navigating away from a view where the task was triggered
  • Canceling that Task’s Parent Task to cancel all of its Child Tasks
  • When another Child Task of the same Parent throws an Error

Async Let

Async Let is a variation of Async/Await that differs from the Await version, in that it will immediately launch a known number of Tasks in parallel and manage them in a slightly different manner than Async/Await. Where an Async/Await call suspends the Parent Task during Child Task execution, the Async Let call allows the Parent Task to continue running normally. 

You would use Async Let when you’re certain that the Async code can run independently. Note that unlike a regular Async/Await Call, you cannot directly cancel Async Let calls.

A further difference is that you can only use Async Let in local declarations, not at the top level.

Use Async Let when you need the results from the call later in your application, not immediately. For example, you could use multiple Async Let calls to load gallery images without blocking the main thread, thereby allowing the user to continue using the application’s GUI while the images load. 

Use Async Let when:

  • You have enough detail to request the information you need prior to making the call 
  • The calls do not depend on another call’s results 
  • You are returning different kinds of data
  • The order in which the app returns results is unimportant

Task Groups

Task Groups allow you to combine an unknown number of parallel Child Task calls that return the same Type of data into a batch, and then wait until the last Child Task finishes before completing the call. This is most useful when the results are a consistent type, such as when combining API responses into a single object. Task Groups only complete after all Child Tasks in the Task Group are complete.

It is important to never mutate the Task Group using code from outside the Task where the Task Group was created. Doing so interleaves data obtained by the Task Group with the data from outside the Task Group which leaves the results inconsistent. 

Using Try Await allows you to handle any potential thrown errors in the grouped call using additional code.

For example, let’s say you have a function that returns a string value and you need to call the function n times. Each time that function returns, you want to append the resultant string to an array of strings:  

Once all the Tasks in the Task Group are complete, you want the Task Group to return a String array. The “of” type for the Task Group is String because the result of the parallel task is a String and the returning type is an array of Strings

Coding UIImages in Task Groups will appear more familiar. For example, let’s say that you have a list of indeterminate size composed of URLs that point to specific images, and a function that downloads an image from each of those URLs and then adds it to an image array returned from the Task Group.

In this case, the “of” type for your Task Group is UIImage, and because the parallel function inside the task is downloading UIImage data, and the returning type for the Task Group is an array of UIImages.

Task Group Example

The Of type for this example Task Group scenario is UIImage and because the parallel function inside the task is downloading UIImage data, the “returning” type of the task group is an array of UIImages.

There are two things happening in this example code. The first is the execution of the parallel downloading task for the individual images located at each URL. The second takes the results from the previous task (the UIIMage) and combines them into a single array of images.

Resources

  • Apple Developer: Getting Started with Swift Concurrency
  • InRhythm Swift Lightning Talk (Deck): Structured Concurrency in Swift
  • Linkedin Video: InRhythm Propel Workshop (Video) 
  • GitHub Repo: Async Await Propel Workshop GitHub Repo 
  • Blog, Antoine van der Lee: Async await in Swift explained with code examples

Written by Mike Adams · Categorized: Code Lounge, InRhythmU, Learning and Development, Product Development, Software Engineering · Tagged: Async Await, best practices, INRHYTHMU, ios, iOS Workshop, learning and growth, Mobile App Development, Mobile Development, Mobile Engineering, Propel Spring Quarterly Summit 2023, software engineering, SwiftUI, ux

Mar 16 2023

An Introduction To Cross-Platform Mobile Development

Author: Minhazur Rahman, Senior Android Developer @ InRhythm

Overview

No alt text provided for this image

As mobile technology continues to evolve, we as developers are faced with the challenge of creating mobile apps that work great on all platforms. Traditionally, this has meant building separate apps for each platform, which is very time consuming and costly. However, with the rise of cross-platform mobile development, developers can now write code once and deploy it across multiple platforms.

We will explore:

  • The pros and con of cross-platform mobile development
  • How it compares to native development
  • Some of the most common tools and frameworks used in cross platform development

What Is Cross-Platform Mobile Development?

No alt text provided for this image

Cross-platform mobile development refers to the process of writing code once and deploying it across multiple platforms, such as iOS and Android. This is achieved using frameworks and tools that allow developers to write code in a single codebase and then compile it for multiple platforms.

Cross-platform development offers several advantages over native development, including:

  • Cost Savings: With cross-platform development, developers can write code once and deploy it across multiple platforms, reducing the time and cost required to develop separate app for each platform
  • Wider Audience: By deploying an app on multiple platforms, developers can reach a wider audience, increasing the app’s potential user base
  • Consistent User Experience: Cross-platform development allows developers to ensure that users have a consistent experience across multiple platforms, improving the overall user experience
No alt text provided for this image

However, cross-platform development also has some limitations, including:

  • Performance Issues: Cross-platform apps may not perform as well as native apps, particularly for complex apps that require heavy processing or graphics
  • Limited Access To Native Features: Cross-platform development may not provide access to all of the native features of each platform, limiting the app’s functionality
  • Development Limitations: Cross-platform development may limit the development process, as developers may need to compromise on certain features or design elements to ensure compatibility across multiple platforms

Cross-Platform Development vs. Native Development

No alt text provided for this image

To better understand the pros and cons of cross-platform development, it’s important to compare it to native development. Native development involves building separate apps for each platform using that platform’s specific language and tools.

Native development offers several advantages, including:

  • Access To Native Features: Native development provides access to all of the native features of each platform, allowing developers to create apps with rich functionality and design
  • Better Performance: Native apps generally perform better than cross-platform apps, particularly for complex apps that require heavy processing or graphics
  • Better User Experience: Native apps can provide a better user experience, as they are designed specifically for each platform, taking into account the unique features and design elements of each platform
No alt text provided for this image

Native development has limitations as well:

  • Time And Cost: Developing separate apps for each platform can be time-consuming and costly, as developers need to learn multiple programming languages and use platform-specific tools
  • Limited Audience: Developing separate apps for each platform may limit the app’s audience, as users may only be able to access the app on one platform
  • Inconsistent User Experience: Developing separate apps for each platform may result in inconsistent user experience, as users may have different experiences depending on the platform they are using

Common Tools and Frameworks For Cross-Platform Development

To make cross-platform development easier, there are several tools and frameworks available that allow developers to write code once and deploy it across multiple platforms. Here are some of the most common ones:

No alt text provided for this image
  • React Native: React Native is a popular framework for building cross-platform apps using JavaScript and React; a popular JavaScript library for building user interfaces. It allows developer to write code once and deploy it on both iOS and Android
No alt text provided for this image
  • Xamarin: Xamarin is a cross-platform development tool that uses C# to build apps for iOS, Android, and Windows. It allows developers to share code between platforms, reducing development time and cost
No alt text provided for this image
  • Flutter: Flutter is a popular framework for building cross-platform apps using Dart: a programming language developed by Google. It allows developers to create beautiful and fast apps that work seamlessly across multiple platforms
No alt text provided for this image
  • Ionic: Ionic is a popular open-source framework for building cross-platform mobile apps using web technologies such as HTML, CSS, and JavaScript. It allows developers to create hybrid apps that work on both iOS and Android

When To Choose Cross-Platform Over Native Development

No alt text provided for this image

Choosing between cross-platform and native development depends on several factors, including the app’s complexity, budget, and timeline.

Here are some scenarios where cross-platform development may be the better option:

  • Limited Budget: If you have a limited budget, cross-platform development can be a cost-effective solution as it allows you to write code once and deploy it on multiple platforms
  • Tight Timeline: If you need to develop an app quickly, cross-platform development can help you save time as you don’t need to write separate code for each platform
  • Simple Apps: If your app is simple and doesn’t require access to many native features, cross-platform development can be a good option
  • Maintenance: If you need to maintain your app on multiple platforms, cross-platform development can be a more efficient solution as you can make changes to the codebase once and deploy it across all platforms
No alt text provided for this image

However, there are also scenarios where native development may be the better option, such as:

  • Complex Apps: If your app requires access to many native features or requires heavy processing or graphics, native development may be the better option as it can provide better performance
  • Design: If your app requires a unique design that is specific to each platform, native development may be the better option as it allows you to design the app specifically for each platform
  • Budget: If you have a larger budget, native development may be a better option as it can provide a better user experience and access to all of the native features of each platform

Conclusion

No alt text provided for this image

Cross-platform mobile development is a popular solution for creating apps that work seamlessly across multiple platforms. While it offers several advantages, such as cost savings and a wider audience, it also has limitations, such as performance issues and limited access to native feature.

Choosing between cross-platform and native development depends on several factors, including the app’s complexity, budget, and timeline. By weighing the pros and cons, developers can choose the best solution for their app development needs.

Written by Kaela Coppinger · Categorized: Code Lounge, InRhythmU, Learning and Development, Product Development · Tagged: Android, best practices, Cross Platform Development, INRHYTHMU, JavaScript, learning and growth, Mobile App Development, Mobile Apps, Mobile Development

Jan 10 2023

Why You Should Migrate Away From AngularJS

Overview

With the legacy experience of the Angular Javascript framework, web developers have grown to lean on the framework as a go-to tool. Today, we wanted to go through a few of the reasons why you should look to migrate your existing AngularJS projects (any Angular release version under 2) to a more modern and actively supported framework (or library).

Even though AngularJS is a fantastic piece of technology that surely was top of its class when it came out (October 2010) and despite the fact that we’ve enjoyed working with its successor Angular.io (also known as Angular 2+), AngularJS has become outdated (EOL December 2021), and a risk to your company in a variety of different ways.

No alt text provided for this image
@2017, Scott Adams, Inc.

The framework has reached end of support (Version Support Status). This means that it has become read-only mode, therefore it will not be updated further. The framework has not been developed for over a year now (Release 1.8.2 happened in October 2020), and even though extended support was supposed to end mid-2021, it was extended to December 2021 due to the global pandemic. Here’s a blog post by the Angular team regarding discontinued long term support.

To add some support to the point, Angular was created and mainly maintained by Google. Google recognized the shortcomings of AngularJS, and completely rewrote it to release Angular.io. AngularJS only made it to version 1.8.3, however Angular.io has already made it to major version 13 (current at time of writing), with many more versions to come.

What Could Be Making You Hold On To Your Existing AngularJS Apps

No alt text provided for this image
@2016, Scott Adams, Inc.

Trust us, we’ve been there. You have a perfectly functioning application which needs little maintenance, and you have engineers who know it in and out already. Why invest a part of your budget in fixing something that’s not broken? Why bring in new people that don’t know the product? Why push your engineers to do something new/different to what they’ve been doing?

The Reasons

No alt text provided for this image
  • Technology: As stated earlier, AngularJS is outdated. This means that in its feature-set, performance, and just keeping up with latest developments in Javascript and the web browsers, AngularJS has clearly lagged behind, mainly due to the fact that it has been in maintenance mode and not actively developed on for years. If you stay on this framework, you won’t take advantage of the rapidly evolving web world, and the evolving smart devices, and their new features.
  • Support: As the framework is no longer maintained, any new issues or limitations you encounter will not only lack an answer/help from the AngularJS team (again, not supported anymore), you most probably also won’t have a huge community online to help you with it, like you would have with any modern framework. This could mean a longer time to fix issues that come up in your application, and a rough experience for your engineers and users.
  • Security: Perhaps the biggest reason why you should move away from AngularJS. Like any unsupported package out there, you won’t be protected when any new security exploits are identified, be it within the framework itself, or any of its thousands of dependencies and indirect dependencies (yes, your app can be exploited by vulnerabilities in the dependencies of the dependencies of AngularJS which is your app’s dependency… you get the point). Usually when something like this happens in an actively supported package, a fix will be published quite swiftly in response to it, or any dependency that includes the vulnerability will be updated with a newer version.
  • Talent: Not only do you want to provide the best possible experience for your users, but also for your app engineers. When you are trying to retain or expand your software team, AngularJS will weigh on any engineer’s decision. Engineers will want to work with quality, cutting edge technology. It is hard for engineers to get or even stay excited about working on a framework that has reached end of life. It will be much easier for you to retain and hire engineers if your apps run on modern technologies and following best practices and industry trends. I cannot stress how much easier it will be to fill open positions when your tech stack is attractive for the engineers. You can also think about what will happen once you actually find someone willing to do the job on your legacy system, they will play hard to get and you’ll end up paying more for an engineer that is probably not up to date on industry standards.
  • Business: For current technologies, the help you will get from the online community is massive, which speeds up the time it takes to fix and implement new features, and to resolve critical situations that may arise. Not only your engineers will be happier and more engaged in what they are doing, it also impacts your branding. Are you a company that invests in and works with the latest and greatest? Or a company that settles with whatever is there?

Closing Thoughts

No alt text provided for this image

With confidence, we have seen the impact that migrating legacy applications has had for many of our customers, and it is massive. Not only do applications come alive and look and feel more modern, but engineers come to work in a better mood and eager to get things done, and a true engineering culture is fostered.

Written by Kaela Coppinger · Categorized: Code Lounge, Product Development, Software Engineering, Web Engineering · Tagged: angularjs, best practices, INRHYTHMU, JavaScript, ux, Web Development, web engineering

  • Go to page 1
  • Go to page 2
  • Go to page 3
  • Interim pages omitted …
  • Go to page 7
  • Go to Next Page »

Footer

Interested in learning more?
Connect with Us
InRhythm

110 William St
Suite 2601
New York, NY 10038

1 800 683 7813
get@inrhythm.com

Copyright © 2023 · InRhythm on Genesis Framework · WordPress · Log in

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPT
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
SAVE & ACCEPT