Angular techniques

Here is a list of some Angular techniques, useful when working with Angular applications

Submit value to backend using Post

Output variable from one component and receive by other component

Set and get attributes from HTML templates

How to call an http method without the observable in Angular 2

localStorage and sessionStorage

Subscribe to two observables whose results are needed

Click event

For loop in Angular

Receiving content through http get

Having paramterised routes work

Pass values from one component to another component

Get an incoming JSON object from a URL and work with it in your component

Include a component in another component

Have the application root show component links and the content

Setting up an Angular router

Subscribe to two observables whose results are needed

Use forkJoin to subscribe to more than one observable simultaneously

forkJoin(
  this.service.service1(), this.service.service2(), this.service.service3()
).subscribe((res) => {
  this.funcA(res[0], res[1], res[2]);
});

Another example is:

   forkJoin(
      this.logic10Service.getLogic10(this.item_id),
      this.http.get<ILogic10BaseCategory[]>(this.catsUrl_part1 + this.item_id + this.CatsUrl_part2)
    ).subscribe((res) => {
      console.log("- forkJoin returned " + res[0] + ", and " + res[1]);
      //can start interacting with res[0] and res[1]
      
    })

For more, see https://stackoverflow.com/questions/52317494/is-it-good-way-to-call-subscribe-inside-subscribe

Click event

Call a click event through (click) and call the function that should be initiated. Assuming I have a function in the component called showUpdateables(catName), I can have the following in the html template file:

    <ng-container *ngIf="arrCats">
    <span id="categoryBox" *ngFor="let cat of arrCats;" (click)="showUpdateables(cat.name)">
        {{cat.name}}
    </span>
    </ng-container>

Receiving content through http get

This example will get a typed array of http result through get:

    this.http.get<ILogic10BaseCategory[]>(this.baseCatsForIngsUrl).subscribe(data => {
      console.log("-- successfully got: " + data)
    });

This example will get any http result:

    this.http.get<any[]>(this.catsUrl).subscribe(data=> {
      this.arrCats = data;
      console.log("-arrCats[0]: " + this.arrCats[0]);
    });

More examples can be found at https://jasonwatmore.com/post/2019/09/06/angular-http-get-request-examples

Having paramterised routes work

1>> In the app-routing.module.ts file add a paramter to a route using colon and paramter, in the example below, the id:

const routes: Routes = [
  { path: 'ShowItem/:id', component: ShowItemComponent }
];

2>> In the component where this id is to be utilized, impoty ActivatedRoute from @angular/router:

import {ActivatedRoute} from "@angular/router";

3>> In the constructor of this same class, subscribe to the route.params and start working with the parameter, in this case the id:

 constructor(private route: ActivatedRoute) { 
                this.route.params.subscribe( params => {
                          console.log("- got params.id: " + params.id);
                           this.itemId = params.id 
                });
              }

  itemId: number;
  

* * *

A good example can be found at:

https://codecraft.tv/courses/angular/routing/parameterised-routes/

Pass values from one component to another component

In the component where you will be receiving the value, include in your component ts file the variable with the @Input annotation — with in the class:

  
  @Input()
  item_id: number;

Then, in the component where you are working with the HTML, include the name of the receiving component with the [variable]=”value” parameter:

<div style="border:1px solid green">

    <app-logic10-base-ingredients [item_id]="item.id"></app-logic10-base-ingredients>
</div>

Get an incoming JSON object from a URL and work with it in your component

7 Steps are required to go from a URL holding a JSON result to the final presentation of results in an Angular component:

1>> have the JSON object, eg. localhost:8080/items/meenu_number/1

2>>Have a TypeScript interface that represents the object, eg. IItem


3>> Write the service class (eg. item.service.ts) with the observable on an http.get

import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { Injectable } from '@angular/core';

import { IItem } from './item';

@Injectable({
    providedIn: 'root'
})
export class ItemService {
    private itemUrl = 'http://localhost:8080/items/menu_number/1';

    constructor(private http: HttpClient) { }

    getItem(): Observable<IItem> {
        console.log("link is: " + this.itemUrl);
        return this.http.get<IItem>(this.itemUrl);
    }
}

4>> Subscribe to the observable in the component and save it to a local variable. You can subscribe on the ngOnInit function of the component:

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

import { ItemService } from './item.service';
import { IItem } from './item'

@Component({
  selector: 'app-show-item',
  templateUrl: './show-item.component.html',
  styleUrls: ['./show-item.component.css']
})
export class ShowItemComponent implements OnInit {

  constructor(private itemService: ItemService) { }

  item: IItem;

  ngOnInit(): void {
    console.log("ngOnInit accessed...");
    this.itemService.getItem().subscribe({
      next: gotItem => {
        this.item = gotItem[0];
        console.log("- got item: " + JSON.stringify(gotItem));
        console.log("- item menu number:" + gotItem[0].menu_number)   
        
      },
      error: err => console.log("error: " + err.error)
    })
  }

}

5>> Include the Http module in app.module.ts both as an import and in the imports section as HttpClientModule

//...
import { HttpClientModule } from '@angular/common/http'; 
//...

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

6>> Enable Cross Origins on your server app, eg. the Node.js app:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

7>> Include the object in the template file of your component

<div style="border:1px solid green">

    <ng-container *ngIf="item">
        <p>show-item component works!</p>
        {{ item.menu_number}} . {{ item.name }} <br>
        {{ item.description }}
    
    </ng-container>

    <app-logic10-base-ingredients></app-logic10-base-ingredients>
</div>

Include a component in another component

To include a component in another component use the component’s selector in your new component

If I have a component that has a selector “app-logic10-base-ingredients”, I can include it in my “show-item” component.

To include it, write so in the html file of the “show-item” component:

<div style="border:1px solid green">

    <p>show-item component works!</p>
    <app-logic10-base-ingredients></app-logic10-base-ingredients>
</div>

Have the application root show component links and the content

The app.component.ts is the root as the application loads:

app.component.ts
app.component.spec.ts
app.component.html
app.component.css

The app.component.ts would have content like:

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

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

and the HTML template (app.component.html) can have links to various parts in the component as well as “router-outlet” where a component can be loaded:

App component
<p></p>

<nav>
  <ul>
    <li><a routerLink="/ShowItem" routerLinkActive="active">ShowItem</a></li>
  </ul>
</nav>

<router-outlet></router-outlet>