Categories
Angular JavaScript

How to use Directives in Angular

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 how to use some built-in Angular directives.

Built-in Directives

Angular has some built-in directives. Built-in directives include attribute directives and structural directives.

Built-in Attribute Directives

Attributes directives change the behavior of HTML elements, attributes, properties and components.

The most common attributes are:

  • NgClass — adds or removes a CSS class
  • NgStyle — adds or removes a set of HTML styles
  • NgModel — adds 2-way data binding to an HTML form element.

NgClass

We can add or remove some CSS classes simultaneously with the ngClass directive.

For example, we can write:

app.component.ts :

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

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  canSave = true;  
  isUnchanged = false;  
  isSpecial = true;  
  classes = {  
    saveable: this.canSave,  
    modified: !this.isUnchanged,  
    special: this.isSpecial  
  };  
}

app.component.html :

<div [ngClass]="classes">foo</div>

In the code above, we created the classes field in AppComponent so that we can apply the saveable , modified and special classes to the div in app.component.html .

The 3 classes are applied when the value of the keys in classes are truthy.

Therefore, when we write:

[ngClass]="classes"

in app.component.html , we’ll see the classes applied to the div.

If we only want to toggle one class, we can also write:

app.component.ts :

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

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

app.component.html :

<div [ngClass]="isGreen ? 'green' : null">foo</div>

Then we get the green class applied to the div in app.component.html since isGreen is set to true in AppComponent .

NgStyle

We can use ngStyle to add multiple styles to an element. This is useful for setting dynamic styles on an element.

To use it, we can write:

app.component.ts :

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

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

app.component.html :

<div [style.font-size]="isBig ? '25px' : '12px'">foo</div>

In the code above, we have the isBig field in AppComponent set to true .

Also, we have style.font-size set to an expression that checks if isBig is truthy or not and then set the size accordingly.

Therefore, the font size of the div would be 25px.

We can also use it to set multiple styles. To do this, we can write:

app.component.ts :

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

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  canSave = true;  
  isUnchanged = false;  
  isSpecial = true;  
  styles = {  
    "font-style": this.canSave ? "italic" : "normal",  
    "font-weight": !this.isUnchanged ? "bold" : "normal",  
    "font-size": this.isSpecial ? "24px" : "12px"  
  };  
}

app.component.html :

<div [ngStyle]="styles">foo</div>

In the code above, we have the styles field in AppComponent , with various CSS attribute names as the key. They’ll be set according to what we have in the expression we have as the values.

Then in app.component.html , we set styles of the div to what we have in the styles object with the ngStyle directive.

Therefore, we should see italic, bold and 24px large text.

[(ngModel)]: Two-way binding

We can use ngModel to do 2-way binding between template and component.

It’s useful for getting input data and then displaying it.

For example, we can use it as follows:

app.module.ts :

import { BrowserModule } from "@angular/platform-browser";  
import { NgModule } from "@angular/core";  
import { FormsModule } from "@angular/forms";
import { AppComponent } from "./app.component";

@NgModule({  
  declarations: [AppComponent],  
  imports: [BrowserModule, FormsModule],  
  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 {  
  name: string;  
}

app.component.html :

<input [(ngModel)]="name" />  
<p>{{name}}</p>

In the code above, we added the FormsModule to the imports array in app.module.ts .

Then we added the name field in AppComponent .

Finally, we added an input element with the ngModel directive and a p element with the name variable interpolated.

Then when we type something into the input, it’ll be shown in the p element.

Conclusion

We can use the ngClass directive to set classes on an element.

To set dynamic styles on an element, we can use the ngStyle directive.

To add 2-way data binding, we use the ngModel directive, which is available in the FormsModule .

Categories
Angular JavaScript

Angular Directives — NgSwitch, Input, and Output

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.

Categories
Angular JavaScript

Angular Component Lifecycle Hooks Overview

Angular 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 take a look at the lifecycle hooks of an Angular component.

Lifecycle Hooks

Angular components have a lifecycle managed by Angular.

Angular offers lifecycle hooks to provide visibility to key events of a component and act when a lifecycle event occurs.

We can implement one or more lifecycle interfaces in our component so that we can make sure our components run code during certain lifecycle events.

No directive or component will implement all lifecycle hooks. Angular only calls a directive or component if it’s defined.

For example, we can implement the OnInit interface to run some code when the component is initialized as follows:

import { Component, OnInit } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent implements OnInit {  
  ngOnInit() {  
    console.log("init");  
  }  
}

In the code above, we imported the OnInit interface and then implemented the ngOnInit method.

Lifecycle Sequence

Angular calls the lifecycle hook methods in the following sequence at specific moments.

ngOnChanges()

Responds when Angular sets or resets data-bound input properties. This method receives a SimpleChanges object of the current and previous property values.

It’s called before ngOnInit and whenever one or more data-bound input properties change.

ngOnInit()

Initializes the component or directive after Angular displays the data-bound properties and sets the directive or component’s input properties.

It’s called once after the first ngOnChanges.

ngDoCheck()

Detect and act upon changes that Angular can’t or won’t detect on its own.

It’s called during every change detection run and immediately after ngOnChanges and ngOnInit.

ngAfterContentInit()

Runs after Angular projects external content into the component’s view or the view that the directive is in.

It’s called once after the first ngDoCheck.

ngAfterContentChecked()

Runs after Angular checks the content projected into the directive or component.

It’s called after ngAfterContentInit and every subsequent ngDoCheck.

ngAfterViewInit()

Runs after Angular initializes the component’s view and child views or the view the directive is in.

It’s called once after the first ngAfterContentChecked.

ngAfterViewChecked()

Runs after Angular component checks the component’s view and child views or the view that a directive is in.

It’s called after the ngAfterViewInit and every subsequent ngAfterContentChecked.

ngOnDestroy()

Cleans up just before Angular destroys the directive or component. Unsubscribe Observables and detach event handlers to avoid memory leaks.

It’s called just before Angular destroys the directive or component.

Interfaces are Optional

Interfaces are optional since it doesn’t appear in the JavaScript since JavaScript doesn’t have interfaces.

The hooks are just called if they’re defined.

However, implementing them means that we won’t forget to implement the hooks that we want to implement.

Other Angular Lifecycle Hooks

Other Angular subsystems may implement their own hooks.

3rd party libraries may also implement their hooks.

OnInit()

Use ngOnInit to perform complex initialization shortly after construction or to set up the component after Angular sets the input properties.

Therefore, we shouldn’t fetch data in the constructor. We should do no more than initialize local variables with simple values in the constructor.

OnDestroy()

We should put cleanup logic in ngOnDestroy. Anything that must be run before Angular destroys the directive should be in here.

This is a place to free resources that won’t be garbage collected automatically.

We should unsubscribe from Observable and DOM events here.

OnChanges()

Whenever input properties change, the ngOnChanges hook is called.

The old and new values are in the SimpleChange object that’s passed into the parameter.

DoCheck()

Use ngDoCheck to detect and act upon changes that Angular doesn’t catch on its own.

Usually, changes from unrelated data elsewhere on the page isn’t detected by Angular, so we have to run something here to update those values.

AfterViewInit() and AfterViewChecked()

AfterViewInit is called after the component or directive is loaded along with the child views.

AfterViewChecked is called right after ngAfterViewInit.

AfterContent Hooks

AfterContent hooks are similar to AfterView hooks. The difference is that AfterView hooks concern ViewChildren , which are child components whose element tags appear within the component’s template.

AfterContent hooks concern ContentChildren, which are child components that Angular projected into the component.

Conclusion

We can use the hooks to run code during various stages of the Angular component or directive’s lifecycle.

They run in a sequence. We can implement them by implementing the interfaces or just define the methods with the given names in our component or directive class.

Categories
Angular JavaScript

Accepting User Input with Angular

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 how to accept user inputs with Angular.

User Input

We can use Angular event bindings to respond to any DOM event.

Many DOM events are triggered by user input. Bindings let us provide a way to get input from users.

For example, we can listen to button clicks 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 {  
  onClickMe() {  
    alert("clicked");  
  }  
}

app.component.html :

<button (click)="onClickMe()">Click me!</button>

In the code above, we have the onClickMe method to display an alert.

Then in app.component.html , we added a button which is bound to the click and calls onClickMe when it’s clicked.

Get User Input From the $event Object

DOM events carry a payload of information that may useful to the component. We can access that information by referencing the $event object.

For example, we can write:

app.component.ts :

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

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  keysPressed: string[] = [];  
  onKeyUp(event) {  
    this.keysPressed.push(event.key);  
  }  
}

app.component.html :

<input (keyup)="onKeyUp($event)" />  
<p>{{keysPressed.join(',')}}</p>

In the code above, we have the onKeyUp method of AppComponent which called on the keyup event of input.

In onKeyUp , we push the key that was pressed into the this.keyPressed array.

Then in the template, we call join to combine the strings of the keys that are pressed together.

Type the $event

We can use the KeyboardEvent type to type $event for keyboard events.

We can type the element with the HTMLInputElement type.

For example, we can write the following code:

app.component.ts :

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

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  values: string[] = [];  
  onKeyUp(event: KeyboardEvent) {  
    this.values.push((event.target as HTMLInputElement).value);  
  }  
}

app.component.html :

<input (keyup)="onKeyUp($event)" />  
<p>{{values.join(',')}}</p>

In AppComponent above, we set the event to the KeyboardEvent type and casted the event.target to the HTMLInputElement type.

This way, we get auto-complete and so we’re less likely to make mistakes.

However, passing in the whole $event object to the component reveals too many details about the event and so creates tight coupling between the template and the component.

Get User Input From a Template Reference Variable

We can use template reference variables to get input values.

For example, we can do that 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 {}

app.component.html :

<input #box (keyup)="null" />  
<p>{{box.value}}</p>

On the code above, we have the keyup handler set to null and we added the #box reference variable to the input box.

Then we render the value of the #box input by referencing box.value .

When we type in something into the input box, we’ll see the value displayed in the p element.

This is better than using the $event object to get the value since it doesn’t we don’t have to access the $event object to get the value. Key Event Filtering

We can listen for specific keypresses in an element by specifying the key with the key attribute.

For example, if we want to listen to presses of the Enter key, we can write the following:

app.component.html :

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

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

app.component.html :

<input #box (keyup.enter)="onEnter(box.value)" />

In the code above, we have the onEnter method in AppComponent that takes the value entered into the input box.

Then in app.component.html , we added the #box template variable to the input and have:

(keyup.enter)="onEnter(box.value)"

to listen to keypresses of the Enter key and pass in the value entered into the input to display the alert by calling onEnter with the value passed in.

On Blur

We can listen to the blur event of an element by passing an event listener to an element.

For example, we can write:

app.component.ts :

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

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  value: string;  
  update(value) {  
    this.value = value;  
  }  
}

app.component.html :

<input #box (blur)="update(box.value)" />  
<p>{{value}}</p>

In the code above, we add the #box template variable to the input box and we added a blur event listener by setting (blur) to the update method in AppComponent .

The update method takes an inputted value and sets it to this.value so we can display it in our template.

Then when we type in something into the input and then move the cursor away from the input, we’ll see the value displayed in the p element.

Conclusion

We can handle user inputs by listening to various event listeners.

To get the event object emitted by the event, we can reference the $event object.

To make getting inputted values easier, we can add a template reference variable to the element in the template and then get the properties we want from it.

Categories
Angular JavaScript TypeScript

How to do Localization and Translation in Angular

With the modular structure of Angular apps, adding localization and translation features to it is easy. The most popular Angular add-on is ngx-translate . Angular 2+ is supported by ngx-translate .

Given an existing Angular app, we can install ngx-translate by running npm i ngx-translate .

After installing the package, make sure you have the following in your Angular module file. For example, in app.module.ts , we have:

export function HttpLoaderFactory(http: HttpClient) {  
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');  
}

This allow us to load our JSON translation files from the ./assets/i18n/ . The JSON file should be named according to standard language codes listed in the ‘639–1’ column in the table of https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes. ngx-translate will load it into the Angular app, with its HTTP loader via a GET request.

app.module.ts should look something this, given all of these components and libraries are included in the app:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule, Routes } from '@angular/router';
import { PaginationModule } from 'ngx-bootstrap/pagination';
import { AppComponent } from './app.component';
import { AccountPageComponent } from './account-page/account-page.component';
import { LoginPageComponent } from './login-page/login-page.component';
import { RegisterPageComponent } from './register-page/register-page.component';
import { MenuPageComponent } from './menu-page/menu-page.component';
import { OrdersPageComponent } from './orders-page/orders-page.component';
import { CategoryPageComponent } from './category-page/category-page.component';
import { AboutPageComponent } from './about-page/about-page.component';
import { HomePageComponent } from './home-page/home-page.component';
import { OrderService } from './order.service';
import { MenuService } from './menu.service';
import { UserService } from './user.service';
import { LocationService } from './location.service';
import { CategoryService } from './category.service';
import { RestaurantService } from './restaurant.service';
import { RestaurantsService } from './restaurants.service';
import { IsLoggedInGuard } from './is-logged-in.guard';
import { BottomBarComponent } from './bottom-bar/bottom-bar.component';
import { CartPageComponent } from './cart-page/cart-page.component';
import { VerifyAccountPageComponent } from './verify-account-page/verify-account-page.component';
import { SearchPageComponent } from './search-page/search-page.component';
import { RestaurantPageComponent } from './restaurant-page/restaurant-page.component';
import { ItemPageComponent } from './item-page/item-page.component';
import { ForgotPasswordPageComponent } from './forgot-password-page/forgot-password-page.component';
import { ResetPasswordPageComponent } from './reset-password-page/reset-password-page.component';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
const appRoutes: Routes = [
  { path: 'category/:category', component: CategoryPageComponent },
  { path: 'login', component: LoginPageComponent },
  { path: 'verifyaccount/:userId/:verifyToken', component: VerifyAccountPageComponent },
  { path: 'register', component: RegisterPageComponent, },
  { path: 'resetpassword/:userId/:resetToken', component: ResetPasswordPageComponent, },
  { path: 'cart', component: CartPageComponent, },
  { path: 'forgotpassword', component: ForgotPasswordPageComponent, },
  { path: 'restaurant/:id', component: RestaurantPageComponent },
  { path: 'item/:restaurantId/:menuId/:itemId', component: ItemPageComponent },
  { path: 'menu', component: MenuPageComponent, canActivate: [IsLoggedInGuard] },
  { path: 'orders', component: OrdersPageComponent, canActivate: [IsLoggedInGuard] },
  { path: 'about', component: AboutPageComponent, },
  { path: 'search/:address', component: SearchPageComponent, },
  { path: 'account', component: AccountPageComponent, canActivate: [IsLoggedInGuard] },
  { path: '**', component: HomePageComponent }
];
@NgModule({
  declarations: [
    AppComponent,
    AccountPageComponent,
    LoginPageComponent,
    RegisterPageComponent,
    MenuPageComponent,
    OrdersPageComponent,
    CategoryPageComponent,
    AboutPageComponent,
    HomePageComponent,
    BottomBarComponent,
    CartPageComponent,
    VerifyAccountPageComponent,
    SearchPageComponent,
    RestaurantPageComponent,
    ItemPageComponent,
    ForgotPasswordPageComponent,
    ResetPasswordPageComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot(
      appRoutes, { useHash: true }
    ),
    PaginationModule.forRoot(),
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  providers: [
    RestaurantService,
    RestaurantsService,
    OrderService,
    MenuService,
    UserService,
    LocationService,
    CategoryService,
    IsLoggedInGuard
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

The JSON should be something like this (en.json):

{  
    "Chiyoda": "Chiyoda",  
    "Chūō": "Chūō",  
    "Minato": "Minato",  
    "Shinjuku": "Shinjuku",  
    "Bunkyō": "Bunkyō",  
    "Taitō": "Taitō",  
    "Sumida": "Sumida",  
    "Kōtō": "Kōtō",  
    "Shinagawa": "Shinagawa",  
    "Meguro": "Meguro",  
    "Ōta": "Ōta",  
    "Setagaya": "Setagaya",  
    "Shibuya": "Shibuya",  
    "Nakano": "Nakano",  
    "Suginami": "Suginami",  
    "Toshima": "Toshima",  
    "Kita": "Kita",  
    "Arakawa": "Arakawa",  
    "Itabashi": "Itabashi",  
    "Nerima": "Nerima",  
    "Adachi": "Adachi",  
    "Katsushika": "Katsushika",  
    "Edogawa": "Edogawa",  
    "Select a Location": "Select a Location",  
    "City": "City",  
    "Ward": "Ward",  
    "Submit": "Submit",  
    "Buffet": "Buffet",  
    "Office Packages": "Office Packages",  
    "Family Event": "Family Event",  
    "Seminar": "Seminar",  
    "High tea and dessert table": "High tea and dessert table",  
    "Christmas": "Christmas",  
    "Kids Party": "Kids Party",  
    "Wedding": "Wedding",  
    "Become a partner": "Become a partner",  
    "About": "About"  
}

and foreign language file (jp.json ):

{  
    "Chiyoda": "千代田区",  
    "Chūō": "中央区",  
    "Minato": "港区",  
    "Shinjuku": "新宿区",  
    "Bunkyō": "文京区",  
    "Taitō": "台東区",  
    "Sumida": "墨田区",  
    "Kōtō": "江東区",  
    "Shinagawa": "品川区",  
    "Meguro": "目黒区",  
    "Ōta": "大田区",  
    "Setagaya": "世田谷区",  
    "Shibuya": "渋谷区",  
    "Nakano": "中野区",  
    "Suginami": "杉並区",  
    "Toshima": "豊島区",  
    "Kita": "北区",  
    "Arakawa": "荒川区",  
    "Itabashi": "板橋区",  
    "Nerima": "練馬区",  
    "Adachi": "足立区",  
    "Katsushika": "葛飾区",  
    "Edogawa": "江戸川区",  
    "Select a Location": "地域を選択",  
    "City": "都市",  
    "Ward": "市区町村",  
    "Submit": "検索",  
    "Buffet": "ビュッフェ",  
    "Office Packages": "お弁当",  
    "Family Event": "家族行事",  
    "Seminar": "セミナー",  
    "High tea and dessert table": "デザート",  
    "Christmas": "クリスマス",  
    "Kids Party": "子供向けパーティー",  
    "Wedding": "ウェディング",  
    "Become a partner": "パートナー提携",  
    "About": "私たちについて"  
}

You can also nest your translations in a lower level in your JSON file, like so:

{  
  "text":{      
    "Chiyoda": "千代田区",  
    "Chūō": "中央区",  
    "Minato": "港区",  
    "Shinjuku": "新宿区",  
    "Bunkyō": "文京区",  
    "Taitō": "台東区",  
    "Sumida": "墨田区",  
    "Kōtō": "江東区",  
    "Shinagawa": "品川区",  
    "Meguro": "目黒区",  
    "Ōta": "大田区",  
    "Setagaya": "世田谷区",  
    "Shibuya": "渋谷区",  
    "Nakano": "中野区",  
    "Suginami": "杉並区",  
    "Toshima": "豊島区",  
    "Kita": "北区",  
    "Arakawa": "荒川区",  
    "Itabashi": "板橋区",  
    "Nerima": "練馬区",  
    "Adachi": "足立区",  
    "Katsushika": "葛飾区",  
    "Edogawa": "江戸川区",  
    "Select a Location": "地域を選択",  
    "City": "都市",  
    "Ward": "市区町村",  
    "Submit": "検索",  
    "Buffet": "ビュッフェ",  
    "Office Packages": "お弁当",  
    "Family Event": "家族行事",  
    "Seminar": "セミナー",  
    "High tea and dessert table": "デザート",  
    "Christmas": "クリスマス",  
    "Kids Party": "子供向けパーティー",  
    "Wedding": "ウェディング",  
    "Become a partner": "パートナー提携",  
    "About": "私たちについて"  
  }  
}

Then in your template, you use the keys with the translate filter in to get translated text:

{{'Select a Location' | translate}}

If the translations in JSON is nested in another property, you can display them like so:

{{'text.About' | translate}}

Note that you cannot have spaces in your keys if you use the dot notation.

With this, the Select a Location key is looked up in the JSON, and depending on the language you set, it’ll get the right text from the value gotten from the key. If the value does not existing for the given key, then it will display the translate key.

Language can be changed in the code by injecting the TranslateService into your code. For example, in your component code, you do the following:

constructor(private translate: TranslateService)

Then you can do:

this.translate.use('jp');

to set the app to display Japanese.

You can also display the default language like so:

this.translate.setDefaultLang('jp');

Translations in Angular is straightforward. It is just a matter of installing a new package, adding the translation, setting the language, and make sure that it displays in the template.