Use the Angular project template with ASP.NET Core

Create a new app

dotnet new angular -o my-new-app
cd my-new-app

Add pages, images, styles, modules, etc.

The ClientApp directory contains a standard Angular CLI app

Run ng commands

remove package-lock.json then :

cd ClientApp
npm install

Install npm packages

cd ClientApp
npm install --save <package_name>

Run “ng serve” independently

cd ClientApp
npm start

Use npm start to launch the Angular CLI development server, not ng serve, so that the configuration in package.json is respected. To pass additional parameters to the Angular CLI server, add them to the relevant scripts line in your package.json file.

In your Startup class, replace the spa.UseAngularCliServer invocation with the following:

spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");

References
https://docs.microsoft.com/en-us/aspnet/core/client-side/spa/angular?view=aspnetcore-6.0&tabs=visual-studio

Pass a value to the Resolver on Angular

{
  path: 'project/:id',
  component: ProjectComponent,
  resolve: { data: DataResolver },
  data: { path: 'project/:id' }
}

class DataResolve implements Resolve<string> {
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return route.data['path'];
  }
}
return new Observable<Item>(subscriber => {
  // tslint:disable-next-line
  const itemId = route.params.id;
  this.db.findItemByItemId2(itemId).subscribe(value => {
    subscriber.next(value);
    subscriber.complete();
  });
});

References
https://stackoverflow.com/questions/40297165/angular-2-pass-a-value-to-the-route-data-resolve/49171861

Reloading current route in Angular

@ngModule({
 imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: ‘reload’})],
 exports: [RouterModule],
 })
export const routes: Routes = [
 {
   path: ‘invites’,
   component: InviteComponent,
   children: [
     {
       path: ‘’,
       loadChildren: ‘./pages/invites/invites.module#InvitesModule’,
     },
   ],
   canActivate: [AuthenticationGuard],
   runGuardsAndResolvers: ‘always’,
 }
]
export class InviteComponent implements OnInit, OnDestroy{
 // ... your class variables here
 navigationSubscription;
 constructor(
   // … your declarations here
   private router: Router,
  ) {
   // subscribe to the router events - storing the subscription so
   // we can unsubscribe later. 
   this.navigationSubscription = this.router.events.subscribe((e: any) => {
     // If it is a NavigationEnd event re-initalise the component
     if (e instanceof NavigationEnd) {
       this.initialiseInvites();
     }
   });
 }
 
 initialiseInvites() {
   // Set default values and re-fetch any data you need.
 }
 ngOnDestroy() {
    // avoid memory leaks here by cleaning up after ourselves. If we  
    // don't then we will continue to run our initialiseInvites()   
    // method on every navigationEnd event.
    if (this.navigationSubscription) {  
       this.navigationSubscription.unsubscribe();
    }
  }
}

References
https://medium.com/engineering-on-the-incline/reloading-current-route-on-click-angular-5-1a1bfc740ab2

Angular Component Inheritance

Base Component

// ...
import { Router } from '@angular/router';

constructor(public router: Router) { }

Take note of the accessibility level. It’s important to keep this declaration “public” due to the inheritance.

Inherited Components

export class PageoneComponent 
  extends BaseComponent
  implements OnInit {
    // ...
}
constructor(public router: Router) {
  super(router);
}

References
https://alligator.io/angular/component-inheritance/

Access to HTML element using @ViewChild in Angular

<textarea  #someVar  id="tasknote"
                  name="tasknote"
                  [(ngModel)]="taskNote"
                  placeholder="{{ notePlaceholder }}"
                  style="background-color: pink"
                  (blur)="updateNote() ; noteEditMode = false " (click)="noteEditMode = false"> {{ todo.note }} 

</textarea>
import {ElementRef,Renderer2} from '@angular/core';
@ViewChild('someVar') el:ElementRef;

constructor(private rd: Renderer2) {}

ngAfterViewInit() {
      console.log(this.rd); 
      this.el.nativeElement.focus();      // we can access it after ngAfterViewInit
}

References
https://stackoverflow.com/questions/38944725/how-to-get-dom-element-in-angular-2

Using iframe in Angular

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer} from '@angular/platform-browser';

@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
  constructor(private sanitizer: DomSanitizer) {}
  transform(url) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}
<iframe width="100%" height="300" [src]="url | safe"></iframe>

References
https://stackoverflow.com/questions/38037760/how-to-set-iframe-src-without-causing-unsafe-value-exception

Dynamically switch RTL/LTR on Kendo UI for Angular

This is working but not dynamically, so we need to change this to work

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { RTL } from '@progress/kendo-angular-l10n';


import { AppComponent } from './app.component';

@NgModule({
  imports:      [ BrowserModule, BrowserAnimationsModule, LayoutModule ],

  // Enable Right-to-Left mode for Kendo UI components
  providers:    [{ provide: RTL, useValue: true }],

  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Use a factory provider to dynamically resolve values

export function enableRTL(): boolean {
  const x = document.cookie;
  const dir = getCookie('dir');

  if (dir === 'rtl') {
    return true;
  }
  return false;
}
{provide: RTL, useFactory: enableRTL}

References
https://www.telerik.com/kendo-angular-ui-develop/components/globalization/localization/
https://plnkr.co/edit/EOFoxuwc6ooUm5Ctho2q?p=preview
https://github.com/telerik/kendo-angular/issues/984

Sharing Modules in Angular

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CustomerComponent } from './customer.component';
import { NewItemDirective } from './new-item.directive';
import { OrdersPipe } from './orders.pipe';

@NgModule({
 imports:      [ CommonModule ],
 declarations: [ CustomerComponent, NewItemDirective, OrdersPipe ],
 exports:      [ CustomerComponent, NewItemDirective, OrdersPipe,
                 CommonModule, FormsModule ]
})
export class SharedModule { }

References
https://angular.io/guide/sharing-ngmodules