Angular Directives — NgSwitch, Input, and Output
Tags: angular, webdev, programming, javascript
Published: 2021-01-23 00:17:09

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Angular is a popular front-end framework made by Google. Like other popular front-end frameworks, it uses a component-based architecture to structure apps.

In this article, we’ll look at the `NgSwitch` directive, template variables, and `Input` and `Ouput` syntax.

The `NgSwitch` directives
=========================

We can use the `NgSwitch` directive to display an item from a list of possible choices.

For example, we can use it as follows:

`app.component.ts`:

```
import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  name = "foo";  
}
```

`app.component.html`:

```
<div [ngSwitch]="name">  
  <p *ngSwitchCase="'foo'">foo</p>  
  <p *ngSwitchCase="'bar'">bar</p>  
  <p *ngSwitchCase="'baz'">baz</p>  
</div>
```

In the code above, we have the `name` field in `AppComponent` set to `'foo'`.

Then in `app.component.html`, we have `ngSwitch` set to `name` so that it checks the value of `name` in `AppComponent` to get what to display.

We have multiple `*ngSwitchCase` with different values so that if `name` is `'foo'`, we display ‘foo’, if `name` is `'bar'` then we display ‘bar’, and if `name` is `'baz'`, we display ‘baz’.

Since `name` is `‘foo’`, we display ‘foo’.

`*ngSwitchCase` works with both native elements and components.

Template Reference Variables (#var)
===================================

A template reference variable is often a reference to a DOM element within a template. It can also refer to a directive, an element. `TemplateRef` or a web component.

For example, we can use it as follows:

`app.component.ts`:

```
import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  call(phone) {  
    alert(`Calling ${phone.value}`);  
  }  
}
```

`app.component.html` :

```
<input #phone placeholder="phone" />  
<button (click)="call(phone)">Call</button>
```

In the code above, we added a `call` method which takes in the `phone` element as the argument and shows an alert with the value typed into the `phone` input.

Then we added `#phone` in `app.component.html` to reference the input element. Also, we added a button to call the `call` method with the `phone` input reference so that we can show the value in the alert.

`NgForm`
========

The `NgForm` directive change behavior and set the value of the template variable to something else.

With it, we can reference the form with a variable inside our outside the form.

For example, we can use `NgForm` as follows:

`app.component.ts`:

```
import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  onSubmit(itemForm) {  
    if (itemForm.invalid) {  
      return;  
    }  
    alert("form submitted");  
  }  
}
```

`app.component.html`:

```
<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">  
  <label>Name <input name="name" ngModel required /> </label>  
  <button type="submit">Submit</button>  
</form>
<div [hidden]="itemForm.form.valid">  
  <p>Missing name</p>  
</div>
```

In the code above, we have the `onSubmit` method in `AppComponent`, which takes the `itemForm` reference. Then we can use it to check for validity in the component before submitting.

Then in `app.component.html`, we created the `#itemForm` variable by using the `ngForm` directive so that we can reference the form and check its validity in the bottom `div` and in `onSubmit` with `itemForm` passed in.

Alternative Syntax
------------------

We can use the `ref-` prefix instead of `#`, so we can write:

```
<input ref-phone placeholder="phone" />  
<button (click)="call(phone)">Call</button>
```

`@Input()` and `@Output()` Properties
=====================================

`@Input` and `@Output` allow Angular to share data between the parent context and child directives and components.

How to use @Input()
-------------------

For example, we can write the following to use `@Input` to pass in data from the parent component to the child:

`app.module.ts`:

```
import { BrowserModule } from '@angular/platform-browser';  
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';  
import { AppComponent } from './app.component';  
import { PersonComponent } from './person/person.component';
@NgModule({  
  declarations: [  
    AppComponent,  
    PersonComponent  
  ],  
  imports: [  
    BrowserModule,  
    AppRoutingModule  
  ],  
  providers: [],  
  bootstrap: [AppComponent]  
})  
export class AppModule { }
```

`app.component.ts`:

```
import { Component } from '@angular/core';

@Component({  
  selector: 'app-root',  
  templateUrl: './app.component.html',  
  styleUrls: ['./app.component.css']  
})  
export class AppComponent {  
  persons = [{ name: 'Jane' }, { name: 'John' }, { name: 'Mary' }];  
}
```

`app.component.html`:

```
<app-person *ngFor="let p of persons" [person]='p'></app-person>
```

`person.component.ts`:

```
import { Component, OnInit, Input } from '@angular/core';

@Component({  
  selector: 'app-person',  
  templateUrl: './person.component.html',  
  styleUrls: ['./person.component.css']  
})  
export class PersonComponent {  
  @Input() person;  
}
```

`person.component.html`:

```
<div>{{person.name}}</div>
```

In the code above, we created a `PersonComponent` component and then included it in the `declarations` array of `AppModule`.

Then in `AppComponent`, we have:

```
persons = [{ name: 'Jane' }, { name: 'John' }, { name: 'Mary' }];
```

and `*ngFor` in `app.component.html` to loop through the items and render the `PersonComponent`.

We pass in `p` as the value of the `person` property and then it’ll be the value of `person` in the `PersonComponent`.

Finally, we display the `name` value of `person` in `person.component.html`.

In the end, we should see:

```
JaneJohnMary
```

displayed on the screen.

How to use @Output()
--------------------

We can use the `@Output` decorator in the child component or directive to pass data from child to parent.

For example, we can use it as follows:

`app.module.ts`:

```
import { BrowserModule } from '@angular/platform-browser';  
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';  
import { AppComponent } from './app.component';  
import { PersonComponent } from './person/person.component';

@NgModule({  
  declarations: [  
    AppComponent,  
    PersonComponent  
  ],  
  imports: [  
    BrowserModule,  
    AppRoutingModule  
  ],  
  providers: [],  
  bootstrap: [AppComponent]  
})  
export class AppModule { }
```

`app.component.ts`:

```
import { Component } from '@angular/core';

@Component({  
  selector: 'app-root',  
  templateUrl: './app.component.html',  
  styleUrls: ['./app.component.css']  
})  
export class AppComponent {  
  emittedName: string;  
}
```

`app.component.html`:

```
<app-person (name)='emittedName = $event'></app-person>  
<p>{{emittedName}}</p>
```

`person.component.ts`:

```
import { Component, Output, EventEmitter } from '@angular/core';

@Component({  
  selector: 'app-person',  
  templateUrl: './person.component.html',  
  styleUrls: ['./person.component.css']  
})  
export class PersonComponent {  
  @Output() name = new EventEmitter<string>();  
  emitName() {  
    this.name.emit('Jane');  
  }  
}
```

`person.component.html`:

```
<button (click)='emitName()'>Get Name</button>
```

In the code above, we have the button in `person.component.html` which calls the `PersonComponent`’s `emitName` method to emit the string `'Jane'` to the parent component with the `EventEmitter`.

Then in the parent component, `AppComponent`, we have:

```
<app-person (name)='emittedName = $event'></app-person>
```

in `app.component.html`.

`$event` has the value emitted from the `name` emitter. Then we set it to `emittedName` and displayed it.

@Input() and @Output() together
===============================

We can use them together.

For example, we can write:

```
<app-input-output [item]="currentItem" (deleteRequest)="deleteItem($event)"></app-input-output>
```

In the code above, we pass `currentItem` to the `item` property to the `app-input-output` component.

The `deleteRequest` is emitted from `app-input-output` and then the `deleteItem` method is called with what’s passed from the child when `deleteRequest` is emitted.

We can pass in a name to `Input` and `Output` to change the name of them respective and then we can reference them with that name in our templates.

Conclusion
==========

We can use `NgSwitch` to display an item depending on value of something in the component.

Template variables let us reference DOM elements in our templates and access its properties.

With `Input` and `Output`, we can pass data to a child component or directive and pass items from child to parent respectively.