Skip to content

Commit

Permalink
35381 angular update (#35632)
Browse files Browse the repository at this point in the history
* Angular Router URL fix

* Fix: Angular Tutorial document update with latest version

* Review changes added

* Changed Directives to Control blocks

---------

Co-authored-by: Brian Thomas Smith <[email protected]>
  • Loading branch information
ragul1697 and bsmth authored Dec 20, 2024
1 parent c9f96f0 commit c86c36c
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 69 deletions.
2 changes: 1 addition & 1 deletion files/en-us/glossary/router/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ For network layer context:

For SPA in application layer context, most of the popular SPA frameworks have their routing libraries:

- [Angular router](https://angular.io/guide/router)
- [Angular router](https://angular.dev/guide/routing/common-router-tasks)
- [React router](https://reactrouter.com/)
- [Vue router](https://router.vuejs.org/)
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ The HTTP server also lets you access the app at your computer's IP address from
At this point, you've built a basic application, but your Angular journey is just beginning.
You can learn more by exploring the Angular documentation, such as:

- [Tour of Heroes](https://angular.io/tutorial): An in-depth tutorial highlighting Angular features, such as using services, navigation, and getting data from a server.
- The Angular [Components](https://angular.io/guide/component-overview) guides: A series of articles that cover topics such as lifecycle, component interaction, and view encapsulation.
- The [Forms](https://angular.io/guide/forms-overview) guides: Articles that guide you through building reactive forms in Angular, validating input, and building dynamic forms.
- [Tutorials](https://angular.dev/tutorials): An in-depth tutorial highlighting Angular features, such as using services, navigation, and getting data from a server.
- The Angular [Components](https://angular.dev/guide/components) guides: A series of articles that cover topics such as lifecycle, component interaction, and view encapsulation.
- The [Forms](https://angular.dev/guide/forms) guides: Articles that guide you through building reactive forms in Angular, validating input, and building dynamic forms.

## Summary

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ page-type: learn-module-chapter
It is now time to look at Google's Angular framework, another popular option that you'll come across often. In this article we look at what Angular has to offer, install the prerequisites and set up a sample app, and look at Angular's basic architecture.

> [!NOTE]
> This tutorial targets [Angular version 17](https://v17.angular.io/guide/update-to-version-17) and was last revised in March 2024 (`Angular CLI: 17.3.0`).
> This tutorial targets [Angular version 18](https://angular.dev/overview) and was last revised in August 2024 (`Angular CLI: 18.2.1`).
<table>
<tbody>
Expand Down Expand Up @@ -50,13 +50,13 @@ When you build applications with Angular, you're taking advantage of a platform

Before you start exploring the Angular platform, you should know about the Angular CLI. The Angular CLI is the fastest, easiest, and recommended way to develop Angular applications. The Angular CLI makes a number of tasks easy. Here are some example commands that you'll use frequently:

| Command | Description |
| ------------------------------------------------ | --------------------------------------------------------------------- |
| [`ng build`](https://angular.io/cli/build) | Compiles an Angular app into an output directory. |
| [`ng serve`](https://angular.io/cli/serve) | Builds and serves your application, rebuilding on file changes. |
| [`ng generate`](https://angular.io/cli/generate) | Generates or modifies files based on a schematic. |
| [`ng test`](https://angular.io/cli/test) | Runs unit tests on a given project. |
| [`ng e2e`](https://angular.io/cli/e2e) | Builds and serves an Angular application, then runs end-to-end tests. |
| Command | Description |
| ------------------------------------------------- | --------------------------------------------------------------------- |
| [`ng build`](https://angular.dev/cli/build) | Compiles an Angular app into an output directory. |
| [`ng serve`](https://angular.dev/cli/serve) | Builds and serves your application, rebuilding on file changes. |
| [`ng generate`](https://angular.dev/cli/generate) | Generates or modifies files based on a schematic. |
| [`ng test`](https://angular.dev/cli/test) | Runs unit tests on a given project. |
| [`ng e2e`](https://angular.dev/cli/e2e) | Builds and serves an Angular application, then runs end-to-end tests. |

You'll find the Angular CLI to be a valuable tool for building out your applications.

Expand All @@ -70,7 +70,7 @@ To install Angular on your local system, you need the following:

- **Node.js**

Angular requires a [active LTS or maintenance LTS](https://nodejs.org/en/about/previous-releases) version of Node.js. For information about specific version requirements, see the [Version compatibility](https://angular.io/guide/versions) page.
Angular requires a [active LTS or maintenance LTS](https://nodejs.org/en/about/previous-releases) version of Node.js. For information about specific version requirements, see the [Version compatibility](https://angular.dev/reference/versions) page.

For more information on installing Node.js, see [nodejs.org](https://nodejs.org/en/download/package-manager).
If you are unsure what version of Node.js runs on your system, run `node -v` in a terminal window.
Expand All @@ -92,7 +92,7 @@ npm install -g @angular/cli
```

Angular CLI commands all start with `ng`, followed by what you'd like the CLI to do.
Create a new directory where you want to build your app, and switch to the directory in the terminal. Then use the following [`ng new`](https://angular.io/cli/new) command to create a new application called `todo`:
Create a new directory where you want to build your app, and switch to the directory in the terminal. Then use the following [`ng new`](https://angular.dev/cli/new) command to create a new application called `todo`:

```bash
ng new todo --routing=false --style=css --ssr=false
Expand All @@ -102,11 +102,11 @@ The `ng new` command creates a minimal starter Angular application.
The additional flags, `--routing` and `--style`, and `--ssr` define how to handle navigation and styles in the application, and configures server-side rendering.
This tutorial describes these features later in more detail.

The first time you run `ng`, you may be asked if you want to enable terminal [autocompletion](https://angular.io/cli/completion) and analytics.
The first time you run `ng`, you may be asked if you want to enable terminal [autocompletion](https://angular.dev/cli/completion) and analytics.
Autocompletion is convenient because pressing <kbd>TAB</kbd> while typing `ng` commands will show possible options and will autocomplete arguments.

You can also decide if you want to allow analytics about the CLI usage to be sent to Angular maintainers at Google.
To find out more about analytics, see the [Angular `ng analytics` CLI documentation](https://angular.io/cli/analytics).
To find out more about analytics, see the [Angular `ng analytics` CLI documentation](https://angular.dev/cli/analytics).

To run your `todo` application, navigate into your new project with the `cd` command and run `ng serve`:

Expand Down Expand Up @@ -149,7 +149,7 @@ In this way, you are using the best practices from the very beginning.
The Angular CLI also generates a file for component testing called `app.component.spec.ts`, but this tutorial doesn't go into testing, so you can ignore that file.
Whenever you generate a component, the CLI creates these files in a directory with the name you specify and we'll see an example of that later.

To learn more about testing, see the [Angular testing guide](https://angular.io/guide/testing).
To learn more about testing, see the [Angular testing guide](https://angular.dev/guide/testing).

## The structure of an Angular application

Expand Down Expand Up @@ -179,9 +179,10 @@ import { Component } from "@angular/core";
@Component({
selector: "app-item",
standalone: true,
imports: [],
// the following metadata specifies the location of the other parts of the component
templateUrl: "./item.component.html",
styleUrls: ["./item.component.css"],
styleUrl: "./item.component.css",
})
export class ItemComponent {
// code goes here
Expand Down Expand Up @@ -246,8 +247,9 @@ import { Component } from "@angular/core";
@Component({
selector: "app-root",
standalone: true,
imports: [],
template: "<h1>\{{ title }}</h1>",
styleUrls: ["./app.component.css"],
styleUrl: "./app.component.css",
})
export class AppComponent {
title = "To do application";
Expand Down Expand Up @@ -275,25 +277,25 @@ To include the styles directly in the component decorator, use the `styles` prop
})
```

Typically, a component uses styles in a separate file using the `styleUrls` property:
Typically, a component uses styles in a separate file.
You can use the `styleUrl` property with the path to the CSS file as a string or `styleUrls` with an array of strings if there are multiple CSS stylesheets you want to include:

```js
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
styleUrl: './app.component.css'
})
```

With component-specific styles, you can organize your CSS so that it is easily maintainable and portable.

### Standalone components

It's recommended to [make components standalone](https://angular.io/guide/component-overview#creating-a-component-manually-1) unless a project already makes use of [NgModules](https://angular.io/guide/ngmodules) (Angular modules) to organize code.
This tutorial uses [standalone components](https://angular.io/guide/standalone-components) which are easier to start with.
It's recommended to [make components standalone](https://angular.dev/guide/components/importing#standalone-components) unless a project already makes use of [NgModules](https://angular.dev/guide/ngmodules) (Angular modules) to organize code.
This tutorial uses [standalone components](https://angular.dev/guide/components/importing#standalone-components) which are easier to start with.

It's common to import [`CommonModule`](https://angular.io/api/common/CommonModule) so that your component can make use of common [directives](https://angular.io/api/common#directives) and [pipes](https://angular.io/api/common#pipes).
This tutorial makes use of `ngFor` and `ngIf`, so we can make sure they're available like so:
It's common to import [`CommonModule`](https://angular.dev/api/common/CommonModule) so that your component can make use of common [directives](https://angular.dev/guide/directives) and [pipes](https://angular.dev/guide/pipes).

```js
import { Component } from "@angular/core";
Expand All @@ -303,7 +305,7 @@ import { CommonModule } from '@angular/common';
standalone: true,
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
styleUrl: './app.component.css',
imports: [CommonModule],
})
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,16 @@ Add markup for managing items by replacing the placeholder content in `item.comp
[checked]="item.done" />
<label [for]="item.description">\{{item.description}}</label>

<div class="btn-wrapper" *ngIf="!editable">
@if (!editable) {
<div class="btn-wrapper">
<button class="btn" (click)="editable = !editable">Edit</button>
<button class="btn btn-warn" (click)="remove.emit()">Delete</button>
</div>
}

<!-- This section shows only if user clicks Edit button -->
<div *ngIf="editable">
@if (editable) {
<div>
<input
class="sm-text-input"
placeholder="edit item"
Expand All @@ -108,6 +111,7 @@ Add markup for managing items by replacing the placeholder content in `item.comp
</button>
</div>
</div>
}
</div>
```

Expand All @@ -117,25 +121,28 @@ Angular uses `\{{item.description}}` to retrieve the description of the current
The next section explains how components share data in detail.

The next two buttons for editing and deleting the current item are within a `<div>`.
On this `<div>` is an `*ngIf`, a built-in Angular directive that you can use to dynamically change the structure of the DOM.
This `*ngIf` means that if `editable` is `false`, this `<div>` is in the DOM. If `editable` is `true`, Angular removes this `<div>` from the DOM.
On this `<div>` is an `@if` block that you can use to render parts of a template based on a condition.
This `@if` means that if `editable` is `false`, this `<div>` is rendered in the template. If `editable` is `true`, Angular removes this `<div>` from the DOM.

```html
<div class="btn-wrapper" *ngIf="!editable">
@if (!editable) {
<div class="btn-wrapper">
<button class="btn" (click)="editable = !editable">Edit</button>
<button class="btn btn-warn" (click)="remove.emit()">Delete</button>
</div>
}
```

When a user clicks the **Edit** button, `editable` becomes true, which removes this `<div>` and its children from the DOM.
If, instead of clicking **Edit**, a user clicks **Delete**, the `ItemComponent` raises an event that notifies the `AppComponent` of the deletion.

An `*ngIf` is also on the next `<div>`, but is set to an `editable` value of `true`.
An `@if` is also on the next `<div>`, but is set to an `editable` value of `true`.
In this case, if `editable` is `true`, Angular puts the `<div>` and its child `<input>` and `<button>` elements in the DOM.

```html
<!-- This section shows only if user clicks Edit button -->
<div *ngIf="editable">
@if (editable) {
<div>
<input
class="sm-text-input"
placeholder="edit item"
Expand All @@ -150,6 +157,7 @@ In this case, if `editable` is `true`, Angular puts the `<div>` and its child `<
</button>
</div>
</div>
}
```

With `[value]="item.description"`, the value of the `<input>` is bound to the `description` of the current item.
Expand Down Expand Up @@ -201,7 +209,7 @@ import { Item } from "../item";

The addition of `Input`, `Output`, and `EventEmitter` allows `ItemComponent` to share data with `AppComponent`.
By importing `Item`, the `ItemComponent` can understand what an `item` is.
You can update the `@Component` to use [`CommonModule`](https://angular.io/api/common/CommonModule) in `app/item/item.component.ts` so that we can use the `ngIf` directives:
You can update the `@Component` to use [`CommonModule`](https://angular.dev/api/common/CommonModule) in `app/item/item.component.ts` so that we can use the `@if` blocks:

```js
@Component({
Expand Down Expand Up @@ -233,7 +241,7 @@ export class ItemComponent {
```

The `editable` property helps toggle a section of the template where a user can edit an item.
`editable` is the same property in the HTML as in the `*ngIf` statement, `*ngIf="editable"`.
`editable` is the same property in the HTML as in the `@if` statement, `@if(editable)`.
When you use a property in the template, you must also declare it in the class.

`@Input()`, `@Output()`, and `EventEmitter` facilitate communication between your two components.
Expand All @@ -253,7 +261,7 @@ This `description` is the same string from the `<input>` with the `#editedItem`
If the user doesn't enter a value but clicks **Save**, `saveItem()` returns nothing and does not update the `description`.
If you didn't have this `if` statement, the user could click **Save** with nothing in the HTML `<input>`, and the `description` would become an empty string.

If a user enters text and clicks save, `saveItem()` sets `editable` to false, which causes the `*ngIf` in the template to remove the edit feature and render the **Edit** and **Delete** buttons again.
If a user enters text and clicks save, `saveItem()` sets `editable` to false, which causes the `@if` in the template to remove the edit feature and render the **Edit** and **Delete** buttons again.

Though the application should compile at this point, you need to use the `ItemComponent` in `AppComponent` so you can see the new features in the browser.

Expand All @@ -279,14 +287,15 @@ Replace the current unordered list `<ul>` in `app.component.html` with the follo
```html
<h2>
\{{items.length}}
<span *ngIf="items.length === 1; else elseBlock">item</span>
<ng-template #elseBlock>items</ng-template>
<span> @if (items.length === 1) { item } @else { items } </span>
</h2>

<ul>
<li *ngFor="let i of items">
<app-item (remove)="remove(i)" [item]="i"></app-item>
@for (item of items; track item.description) {
<li>
<app-item (remove)="remove(item)" [item]="item"></app-item>
</li>
}
</ul>
```
Expand All @@ -297,26 +306,24 @@ Change the `imports` in `app.component.ts` to include `ItemComponent` as well as
standalone: true,
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
styleUrl: './app.component.css',
imports: [CommonModule, ItemComponent],
})
```
The double curly brace syntax, `\{{}}`, in the `<h2>` interpolates the length of the `items` array and displays the number.
The `<span>` in the `<h2>` uses an `*ngIf` and `else` to determine whether the `<h2>` should say "item" or "items".
If there is only a single item in the list, the `<span>` containing "item" displays.
Otherwise, if the length of the `items` array is anything other than `1`, the `<ng-template>`, which we've named `elseBlock`, with the syntax `#elseBlock`, shows instead of the `<span>`.
You can use Angular's `<ng-template>` when you don't want content to render by default.
In this case, when the length of the `items` array is not `1`, the `*ngIf` shows the `elseBlock` and not the `<span>`.
The `<span>` in the `<h2>` uses an `@if` and `@else` to determine whether the `<h2>` should say "item" or "items".
If there is only a single item in the list, the `<span>` shows "item".
Otherwise, if the length of the `items` array is anything other than `1`, the `<span>` shows "items".
The `<li>` uses Angular's repeater directive, `*ngFor`, to iterate over all of the items in the `items` array.
Angular's `*ngFor` like `*ngIf`, is another directive that helps you change the structure of the DOM while writing less code.
The `@for` - Angular's control flow block, used to iterate over all of the items in the `items` array.
Angular's `@for` like `@if`, is another block that helps you change the structure of the DOM while writing less code.
For each `item`, Angular repeats the `<li>` and everything within it, which includes `<app-item>`.
This means that for each item in the array, Angular creates another instance of `<app-item>`.
For any number of items in the array, Angular would create that many `<li>` elements.
You can use an `*ngFor` on other elements, too, such as `<div>`, `<span>`, or `<p>`, to name a few.
You can wrap other elements such as `<div>`, `<span`, or `<p>` within an `@for` block.
The `AppComponent` has a `remove()` method for removing the item, which is bound to the `remove` property in the `ItemComponent`.
The `item` property in the square brackets, `[]`, binds the value of `i` between the `AppComponent` and the `ItemComponent`.
Expand Down
Loading

0 comments on commit c86c36c

Please sign in to comment.