Before you update Angular versions, check out these 10 tips for the process.
Angular is a framework that lets us create interactive web frontends for users.
It is a framework that updates often—usually several times a year. This means that keeping up with version updates is important since bug fixes and new features are often introduced with each version. Also, features may become deprecated, and deprecated features may be removed.
In this article, we will look at some tips on how to update our Angular projects easily.
The biggest tip for updating Angular is following the Angular update guide. It has instructions for updating between different versions of Angular—from versions as early as the first 2.0 version all the way to the latest one.
We can choose the version that we update from to the one we want to update to.
Also, it lets us choose the complexity of the Angular app we’re building and has specific instructions depending on the complexity of our app.
After clicking “Show me how to update,” we will see the instructions on how to update our Angular app from the version we have in our project to the one we want to update to.
Usually, the instructions contain the “Before Updating,” “During the Update” and “After the Update” sections.
The “Before Updating” section has the instructions that we should follow before we update to the newer version. It usually has instructions for removing code that uses deprecated features and things that are removed in the version that we update to.
The “During the Update” section has the instructions for doing the updates. It may include things like updating packages, updating the TypeScript version in our project, or switching to a later Node.js version to run our Angular project with.
The “After the Update” has things that we need to do after updating the Angular version in our project. But this section is empty a lot of times.
We should make sure that we follow the instructions precisely so that we won’t run into problems after we make the changes.
Version control will help us a lot with developing code since we can easily revert code if it doesn’t work. Version control systems track the changes in our code as we commit our changes into the code repository.
We can easily revert code since all the committed changes are logged. And uncommitted changes aren’t added to the log until we commit the code. Therefore, we can easily revert code that doesn’t work.
Installing packages and changing code may cause our project to fail so it is very important that we can reverse changes easily if things don’t work. This way, we can start over quickly and we know what we changed.
One of the most common version control systems is Git. The code is stored within a remote repository in Git and we can check out our local copy from the remote repository. Then when we’re ready to save the changes, we commit our code in the remote repository and push the changes to the remote repository.
A version control system that has this structure is called a distributed version control system.
This setup creates redundancy and lets multiple people work on the same repository easily without conflicts since different people can check out the repository to their computer and make their own branches easily.
Then when they’re done, they can merge their code into a shared branch.
We should write some unit tests to test each part of our Angular project automatically. This lets us make sure that our Angular project is running properly after we are done with the update steps.
Angular CLI projects will have the Jasmine test framework included by default.
When we create components, services or other kinds of files with Angular CLI, a test file will be included by default. We can just update that to add some unit tests for our code.
Once we are done writing our tests, then we can run them with the Karma test runner which is built into the Angular CLI.
We can incorporate running unit tests in our build pipeline so that we can make sure our app is running properly whenever we commit any changes.
For instance, in app.component.ts
, we have:
import { Component } from "@angular/core";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
})
export class AppComponent {
title = "angular-test";
}
In app.component.html
, we have:
<div style="text-align:center">
<h1>Welcome to {{ title }}!</h1>
<img
width="300"
alt="Angular Logo"
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="
/>
</div>
Then in app.component.spec.ts
, we can add some tests by writing:
import { TestBed, async } from "@angular/core/testing";
import { RouterTestingModule } from "@angular/router/testing";
import { AppComponent } from "./app.component";
describe("AppComponent", () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent],
}).compileComponents();
}));
it("should create the app", () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'angular-test'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual("angular-test");
});
it("should render title in a h1 tag", () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector("h1").textContent).toContain(
"Welcome to angular-test!"
);
});
});
We call describe
to create a test suite. In the describe
callback, we call it
to create a test by calling it with the test title and a callback with the test code.
In the beforeEach
callback, we write:
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent],
}).compileComponents();
to add the dependencies for the component being tested.
We mount the component being tested with:
const fixture = TestBed.createComponent(AppComponent);
Then we get the rendered HTML with:
const compiled = fixture.debugElement.nativeElement;
in our last test.
We then check that what is rendered is what we expect with:
expect(compiled.querySelector("h1").textContent).toContain(
"Welcome to angular-test!"
);
We just use querySelector
to select the element rendered like we do with plain JavaScript and then we call toContain
to check the textContent
of the element has what we’re looking for.
We can test other parts of our Angular app like services, directives, pipes, etc.
Before we make any changes for updating our Angular project, we should make sure we know the exact Angular version that our project is using.
To do this, we run ng version
in the command to find out the exact version of Angular that is being used in our project.
We should stay up to date with the feature changes in Angular so that we won’t be caught off guard with features that we don’t expect when we do updates.
To find the features of each version, we can check the release announcements. Also, we can check the Angular changelog for added, removed and updated features.
We should make sure that we check if we can update to the version of Angular that we want to update before we make any changes.
To find the most current version of Angular, we run the ng update
command that comes with Angular CLI. If we run ng update
without additional arguments, then the updates available are listed in the output.
To make testing more painless, we can write automated end-to-end tests to test existing features in our Angular app.
We can use various frameworks like Selenium, Cypress or Telerik Test Studio to test our app. They’re all very easy to use and let us test our Angular app like a user without repeatedly pressing the same buttons to do the testing.
Instead, we let the computer interact with the user interface of our app to do the testing. This lets us check if our Angular version update worked properly without testing all the features manually ourselves.
This blog post explains why end-to-end user testing is so key and the five criteria to look at in an E2E support system.
For simple updates like minor version changes, we can use ng update
to update the required packages automatically.
For instance, we run:
ng update @angular/cli @angular/core
to update the @angular/cli
and @angular/core
packages to the latest version with the ng update
command.
We can also specify the exact version that we want to update the packages to with:
ng update @angular/cli@^<major_version> @angular/core@^<major_version>
We replace <major_version>
with the versions that we want to update to.
For instance, we run:
ng update @angular/cli@^10 @angular/core@^10
to update the packages to version 10.
ng update
has many other options that make updating our Angular project easier.
We should make sure Angular CLI is updated when we’re updating our Angular project. This should be done easily with the ng update
command.
We update the @angular/core
and @angular/cli
packages. They should have the same version so that we can run our code without errors.
If we have incompatible versions of different packages, then we may see errors since they aren’t meant to be used with each other. Therefore, it is important that @angular/core
and @angular/cli
have the same version.
Angular is a framework that lets us create interactive web frontends for users. The framework usually updates several times a year.
Since features can change a lot between different versions, we should make sure we keep our Angular project up to date.
We can use the ng update
command and follow the Angular Update Guide to make our Angular project updates more painless. And we can automate our testing with unit and end-to-end tests.
Also, we should use version control systems with our Angular projects so that we can revert changes easily if something goes wrong.
John Au-Yeung is a frontend developer with 6+ years of experience. He is an avid blogger (visit his site at https://thewebdev.info/) and the author of Vue.js 3 By Example.