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

Using ControlValueAccessor to Create Custom Form Controls in Angular

import { Component, forwardRef, HostBinding, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'rating-input',
  template: `
    <span
      *ngFor="let starred of stars; let i = index"
      (click)="onTouched(); rate(i + (starred ? (value > i + 1 ? 1 : 0) : 1))">
      <ng-container *ngIf="starred; else noStar">⭐</ng-container>
      <ng-template #noStar>·</ng-template>
    </span>
  `,
  styles: [`
    span {
      display: inline-block;
      width: 25px;
      line-height: 25px;
      text-align: center;
      cursor: pointer;
    }
  `],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => RatingInputComponent),
      multi: true
    }
  ]
})
export class RatingInputComponent implements ControlValueAccessor {

  stars: boolean[] = Array(5).fill(false);

  // Allow the input to be disabled, and when it is make it somewhat transparent.
  @Input() disabled = false;
  @HostBinding('style.opacity')
  get opacity() {
    return this.disabled ? 0.25 : 1;
  }

  // Function to call when the rating changes.
  onChange = (rating: number) => {};

  // Function to call when the input is touched (when a star is clicked).
  onTouched = () => {};

  get value(): number {
    return this.stars.reduce((total, starred) => {
      return total + (starred ? 1 : 0);
    }, 0);
  }

  rate(rating: number) {
    if (!this.disabled) {
      this.writeValue(rating);
    }
  }

  // Allows Angular to update the model (rating).
  // Update the model and changes needed for the view here.
  writeValue(rating: number): void {
    this.stars = this.stars.map((_, i) => rating > i);
    this.onChange(this.value)
  }

  // Allows Angular to register a function to call when the model (rating) changes.
  // Save the function as a property to call later here.
  registerOnChange(fn: (rating: number) => void): void {
    this.onChange = fn;
  }

  // Allows Angular to register a function to call when the input has been touched.
  // Save the function as a property to call later here.
  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  // Allows Angular to disable the input.
  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

}

References
https://alligator.io/angular/custom-form-control/
https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html