Snippets Collections
(function(){(function(bk){"use strict";var P=Function.prototype.call.bind(Function.prototype.toString);var u=[];var B=[];var n={toString:function(){var a=u.lastIndexOf(this);if(a>=0){return B[a]}return P(this)}};n.toString.prototype=void 0;u=[n.toString];B=[P(Function.prototype.toString)];function C(a,c){if(typeof c!=="function"){return}try{var b=n.toString.call(c);B.push(b);u.push(a);if(Function.prototype.toString!==n.toString){Function.prototype.toString=n.toString}}catch(a){}}var H="ZT4tcOwEFkVEzfiT1T6u";var bo=Object.call.bind(Object.bind,Object.call);var bm=bo(Object.call);var bn=Array.prototype.push;var bq=Array.prototype.indexOf;var bc=Array.prototype.concat;var m=Array.prototype.slice;function D(){return{__callbacks:[],notify:function(g){var h;var d=bm(m,this.__callbacks);var a=d.length;for(var b=a-1;b>=0;--b){try{var e=d[b];if(e!=null){var c=e(g,h);if(c!=null){h=c}}}catch(a){}}return h},register:function(a){bm(bn,this.__callbacks,a)},unregister:function(b){var a=bm(bq,this.__callbacks,b);if(a!==-1){this.__callbacks[a]=null}},__merge:function(a){if(a!=null){this.__callbacks=bm(bc,this.__callbacks,a.__callbacks)}}}}var O=Object.hasOwnProperty;var Q=Object.getPrototypeOf;var S=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var Z=Object.defineProperty;var bg=Object.call.bind(Object.bind,Object.call);var bj=bg(Object.apply);var bd=bg(Object.call);var ba=Object.create;var bh=Function.prototype.bind;var s=Array.prototype.push;var N=Array.prototype.indexOf;var A=["arguments","caller"];var bb;if(typeof Reflect!=="undefined"&&Reflect!=null&&typeof Reflect.construct==="function"){bb=Reflect.construct}else{bb=function(a,c){var d=[null];bj(s,d,c);var e=bj(bh,a,d);return new e}}function W(a,e){var c=a;while(c!=null){var b=S(c,e);if(b!=null){return{containingObj:c,desc:b}}c=Q(c)}return null}var I=ba(null);function M(a){if(a==null){return}I=a}function E(b,e){var a=I[e];if(a==null){return null}for(var f=0;f<a.length;++f){var c=a[f];if(b===c.object){return c}}return null}function be(d,b){var a=I[d];if(a==null){a=[];I[d]=a}bd(s,a,b)}function T(c,h){var a=W(c,h);if(a==null){return void 0}var e=a.containingObj,d=a.desc;var f=E(e,h);if(f!=null){return f.original}var b=d.value;be(h,{object:e,original:b});return b}function U(c,h){var a=W(c,h);if(a==null){return void 0}var e=a.containingObj,d=a.desc;var f=E(e,h);if(f!=null){return f.original}if(bd(O,d,"value")){return void 0}var b=ba(null);if(d.get!=null){b.get=d.get}if(d.set!=null){b.set=d.set}be(h,{object:e,original:b});return b}function J(l,u,o){if(o===void 0){o=false}var b=W(l,u);if(b==null){return null}var q=b.containingObj,p=b.desc;var r=p.configurable,a=p.writable;var h=p.value;if(!bd(O,p,"value")){return null}var f=ba(null);f.value=h;if(r===false&&a===false||typeof h!=="function"){return{originals:f}}var s=E(q,u);if(s!=null){if(s.result!=null){return s.result}h=s.original;f.value=h}var j=D();var k=D();p.value=function g(){var f=arguments;var b=j.notify({args:f,thisObj:this});if(b){if(b.bypassResult!=null){if(b.bypassResult.throw){throw b.bypassResult.value}return b.bypassResult.value}else if(b.args!=null){f=b.args}}var a;var d={args:arguments,thisObj:this,threw:true,result:null};try{if(o&&this instanceof g){a=bb(h,f)}else{a=bj(h,this,f)}d={args:arguments,thisObj:this,threw:false,result:a}}finally{var c=k.notify(d);if(c&&c.bypassResult!=null){if(c.bypassResult.throw){throw c.bypassResult.value}return c.bypassResult.value}}return a};var m=p.value;C(m,h);var e=R(h);for(var v=0;v<e.length;++v){var d=e[v];if(bd(N,A,d)===-1){var n=S(m,d);if(n==null||n.configurable===true||n.writable===true){var i=S(h,d);if(i!=null){if(n!=null&&n.configurable===false&&i.configurable===true){}else{Z(m,d,i)}}}}}try{if(!bd(O,h,"prototype")){m.prototype=void 0}}catch(a){}Z(q,u,p);var c={onBeforeInvoke:j,onAfterInvoke:k,originals:f};be(u,{object:q,result:c,original:h});return c}function L(o,x){var i=W(o,x);if(i==null){return null}var t=i.containingObj,s=i.desc;var u=s.configurable;var y=s,r=y.get,h=y.set;var q=bd(O,s,"value");var j=ba(null);if(u===false||q){if(r!=null){j.get=r}if(h!=null){j.set=h}return{originals:j}}var v=E(t,x);if(v!=null){if(v.result!=null){return v.result}r=v.original.get;h=v.original.set}var p={onAfterGet:void 0,onBeforeGet:void 0,onAfterSet:void 0,onBeforeSet:void 0,originals:{}};if(r!=null){j.get=r;var l=D();var n=D();s.get=function(){var b=l.notify({thisObj:this});if(b&&b.bypassResult!=null){if(b.bypassResult.throw){throw b.bypassResult.value}return b.bypassResult.value}var a;var d={thisObj:this,result:null,threw:true};try{a=bd(r,this);d={thisObj:this,result:a,threw:false}}finally{var c=n.notify(d);if(c&&c.bypassResult!=null){if(c.bypassResult.throw){throw c.bypassResult.value}return c.bypassResult.value}}return a};C(s.get,r);try{if(!bd(O,r,"prototype")){s.get.prototype=void 0}}catch(a){}p.onBeforeGet=l;p.onAfterGet=n}if(h!=null){j.set=h;var k=D();var m=D();s.set=function(b){var f=b;var c=k.notify({param:b,thisObj:this});if(c){if(c.bypassResult!=null){if(c.bypassResult.throw){throw c.bypassResult.value}return c.bypassResult.value}else if(bd(O,c,"param")){f=c.param}}var a;var e={param:b,thisObj:this,result:null,threw:true};try{a=bd(h,this,f);e={param:b,thisObj:this,result:a,threw:false}}finally{var d=m.notify(e);if(d&&d.bypassResult!=null){if(d.bypassResult.throw){throw d.bypassResult.value}return d.bypassResult.value}}return a};C(s.set,h);try{if(!bd(O,h,"prototype")){s.set.prototype=void 0}}catch(a){}p.onBeforeSet=k;p.onAfterSet=m}Z(t,x,s);p.originals=j;be(x,{object:t,result:p,original:j});return p}try{if(typeof document.createEvent==="function"){var X=document.createEvent("CustomEvent");var bf=false;X.initCustomEvent(H,false,false,{exchange:function(a){M(a);bf=true}});dispatchEvent(X);if(!bf){var Y=U(CustomEvent.prototype,"detail");if(Y!=null&&typeof Y.get==="function"){addEventListener(H,function(a){var c=a;var b=bd(Y.get,c);if(b!=null&&typeof b.exchange==="function"){b.exchange(I)}})}}}}catch(a){}var F=Object.create(null);var bp=Object.create(null);{var l="\u202EfDEnaJZLG\u202D";var v=XMLHttpRequest;var y;var x}{var w=window.fetch;var z}var G="\u202EVpLbEMEUW\u202D";var t="-2\u202EVpLbEMEUW\u202D";var r=void 0;var bl=Object.defineProperty.bind(Object);function K(c,b,d,a,f){if(a==="function"){F[c]=J(V(d),b,!!f)}else if(a==="accessor"){F[c]=L(V(d),b)}else if(a==="originalAccessor"){bp[c]=U(V(d),b)}else if(a==="originalFunction"){bp[c]=T(V(d),b)}}function V(b){var a=window;for(var d=0;d<b.length;d++){if(!{}.hasOwnProperty.call(a,b[d])){return void 0}a=a[b[d]]}return a}K("CustomEvent","CustomEvent",[],"function",true);K("Request","Request",[],"originalFunction",true);K("cancelBubble","cancelBubble",["Event","prototype"],"accessor");K("fetch","fetch",[],"function");K("formSubmit","submit",["HTMLFormElement","prototype"],"function");K("preventDefault","preventDefault",["Event","prototype"],"function");K("setRequestHeader","setRequestHeader",["XMLHttpRequest","prototype"],"originalFunction");K("stopImmediatePropagation","stopImmediatePropagation",["Event","prototype"],"function");K("stopPropagation","stopPropagation",["Event","prototype"],"function");K("xhrOpen","open",["XMLHttpRequest","prototype"],"function");K("xhrSend","send",["XMLHttpRequest","prototype"],"function");(function(){if(v==null){return}var j=bp.setRequestHeader!=null?bp.setRequestHeader:F.setRequestHeader!=null?F.setRequestHeader.originals.value:null;if(j==null){return}if(F.xhrOpen!=null){y=function(f,b){if(b!=null&&b.bypassResult!=null||f.args==null||f.args.length<2){return b}var c,a=null;var d;var g=b!=null&&b.args!=null?b.args:f.args;var c=g[0];var a=g[1];var d=g[2]==null?true:g[2];bl(f.thisObj,l,{writable:true,configurable:true,enumerable:false,value:{method:c,url:a}});return{args:[c,a,d]}};F.xhrOpen.onBeforeInvoke.register(y)}if(F.xhrSend!=null){x=function(i,b){if(b!=null&&b.bypassResult!=null){return b}if(r!=null&&l in i.thisObj&&r.shouldHook(i.thisObj[l])){var e=r.getEncodedData();if(e){for(var a in e){if(!{}.hasOwnProperty.call(e,a))continue;var c=e[a];var d=r.config.headerNamePrefix+a;var f=r.chunk(d,c,r.config.headerChunkSize);for(var g in f){if(!{}.hasOwnProperty.call(f,g))continue;j.call(i.thisObj,g,f[g])}}}}return b};F.xhrSend.onBeforeInvoke.register(x)}}());(function(){if(w==null){return}var o=window.Request;if(F.fetch!=null&&window.fetch!=null&&o!=null){var p=function(n,c){var e=n.args;if(c!=null){if(c.bypassResult!=null){return c}if(c.args!=null){e=c.args}}if(e!=null&&e.length>0){var g=e[0];var h=e[1];var f=new o(g,h);var a={url:f.url,method:f.method};if(r!=null&&r.shouldHook(a)){var j=r.getEncodedData();if(j){for(var b in j){if(!{}.hasOwnProperty.call(j,b))continue;var d=j[b];var i=r.config.headerNamePrefix+b;var k=r.chunk(i,d,r.config.headerChunkSize);for(var l in k){if(!{}.hasOwnProperty.call(k,l))continue;f.headers.set(l,k[l])}}}}return{args:[f]}}return c};F.fetch.onBeforeInvoke.register(p)}}());addEventListener(G,function c(b){r=b.detail;removeEventListener(G,c,true)},true);addEventListener(t,function c(b){if(b.detail!=null&&b.detail.exchange!=null){{if(F.xhrOpen!=null&&y!=null){F.xhrOpen.onBeforeInvoke.unregister(y)}if(F.xhrSend!=null&&x!=null){F.xhrSend.onBeforeInvoke.unregister(x)}}{if(F.fetch!=null){F.fetch.onBeforeInvoke.unregister(z)}}b.detail.exchange({instrumented:F})}removeEventListener(t,c,true)},true)}(this))}())
;(function(a){var d=document,w=window,u="/js/vudu_common.js?async&seed=AICczXmLAQAAKrObQ-aY5MVhnyLourgfgbK8nucrMoPvuvJYX7VwvcqfbqbX&sFuxWshNbr--z=q",v="FfAzkmBFs",i="f59afbb3e7e2e459b2c538ab63fecccc";var s=d.currentScript;addEventListener(v,function f(e){e.stopImmediatePropagation();removeEventListener(v,f,!0);e.detail.init("AwGX6HmLAQAAuIJUU875idTA2V1lw4xN4rNEaRQ1XbhdnUOCecBdQfE4mE-bAa7zNTwXTtQxwH8AAEB3AAAAAA==","-IZ0LyOkX=9e57tbPCuJSl4mApFi6d_vWTr2oG3HRgasx8ncEw1NhKDBQzfUjYVqM",[],[736032874,2082269925,1363579862,937703060,1338551666,1829812292,381232339,1618826902],document.currentScript&&document.currentScript.nonce||"SNbliTtfvKD5MNChfSAYzZXo",document.currentScript&&document.currentScript.nonce||"SNbliTtfvKD5MNChfSAYzZXo",[],a)},!0);var o=s&&s.nonce?s.nonce:"";try{s&&s.parentNode.removeChild(s)}catch(e){}{var n=d.createElement("script");n.id=i;n.src=u;n.async=!0;n.nonce=o;d.head.appendChild(n)}}(typeof arguments==="undefined"?void 0:arguments))
;
<h2>Count in component2  =  {{ count }}</h2>
<button (click)='nextCount()'>Next Count from component2</button>
export class Appchild2Component implements OnInit {
 
    count: number;
    constructor(private appsevice: AppService) {
    }
    ngOnInit() {
 
        this.appsevice.count.subscribe(c => {
            this.count = c;
        });
    }
    nextCount() {
        this.appsevice.nextCount();
    }
}
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
 
@Injectable({
    providedIn: 'root'
})
export class AppService {
    counter = 1;
    count: BehaviorSubject<number>;
    constructor() {
 
        this.count = new BehaviorSubject(this.counter);
    }
 
    nextCount() {
        this.count.next(++this.counter);
    }
}
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class CscService {

  apiBaseUrl = 'http://localhost/dev/tcxapp/';

  constructor(private http: HttpClient) { }

  getCountries() {
    return this.http.get(`${this.apiBaseUrl}api/countries`).pipe(
      catchError(this.handleError)
    );
  }

  getStates(countryId: number) {
    return this.http.get(`${this.apiBaseUrl}api/states/${countryId}`).pipe(
      catchError(this.handleError)
    );
  }

  getCities(stateId: number) {
    return this.http.get(`${this.apiBaseUrl}api/cities/${stateId}`).pipe(
      catchError(this.handleError)
    );
  }

  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(`Backend returned code ${error.status}, ` + `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message
    return throwError('Something bad happened. Please try again later.');
  }
}
<div class="create-account">
  <h2>Create Account</h2>
  <div class="row">
    <div class="col-md-6">
      <form [formGroup]="createAccountForm">
        <div class="form-group">
          <select formControlName="country" class="form-control" (change)="onChangeCountry($event.target.value)">
            <option value="">Select country...</option>
            <option *ngFor="let country of countries" [value]="country.id">{{country.country_name}}</option>
          </select>
        </div>
        <div class="form-group">
          <select formControlName="state" class="form-control" (change)="onChangeState($event.target.value)">
            <option value="">Select state...</option>
            <option *ngFor="let state of states" [value]="state.id">{{state.state_name}}</option>
          </select>
        </div>
        <div class="form-group">
          <select formControlName="city" class="form-control">
            <option value="">Select city...</option>
            <option *ngFor="let city of cities" [value]="city.id">{{city.city_name}}</option>
          </select>
        </div>
      </form>
    </div>
  </div>
</div>
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { CscService } from '../csc.service';

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

  createAccountForm: FormGroup;
  countries: {};
  states: {};
  cities: {};

  constructor(private cscService: CscService) { }

  ngOnInit() {
    this.cscService.getCountries().subscribe(
      data => this.countries = data
    );

    this.createAccountForm = new FormGroup({
      country: new FormControl(''),
      state: new FormControl(''),
      city: new FormControl('')
    });
  }

  onChangeCountry(countryId: number) {
    if (countryId) {
      this.cscService.getStates(countryId).subscribe(
        data => {
          this.states = data;
          this.cities = null;
        }
      );
    } else {
      this.states = null;
      this.cities = null;
    }
  }

  onChangeState(stateId: number) {
    if (stateId) {
      this.cscService.getCities(stateId).subscribe(
        data => this.cities = data
      );
    } else {
      this.cities = null;
    }
  }

}
import { Component, OnDestroy, OnInit } from '@angular/core';
// RxJs 6.x+ import paths
import { filter, startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { BookService } from '../books.service';

@Component({
    selector: 'app-books',
    templateUrl: './books.component.html'
})
export class BooksComponent implements OnDestroy, OnInit {
    private ngUnsubscribe = new Subject<void>();

    constructor(private booksService: BookService) { }

    ngOnInit() {
        this.booksService.getBooks()
            .pipe(
               startWith([]),
               filter(books => books.length > 0),
               takeUntil(this.ngUnsubscribe)
            )
            .subscribe(books => console.log(books));

        this.booksService.getArchivedBooks()
            .pipe(takeUntil(this.ngUnsubscribe))
            .subscribe(archivedBooks => console.log(archivedBooks));
    }

    ngOnDestroy() {
        this.ngUnsubscribe.next();
        this.ngUnsubscribe.complete();
    }
}
<div id="assistant">
  <button id="assistant-popup-button" (click)="openSupportPopup()">
    Chat Support?
  </button>
  <div id="assistant-popup" [style.display]="isOpen ? 'block' : 'none'">
    <div id="assistant-popup-header">
      Your friendly Assistant
      <button id="assistant-popup-close-button" (click)="openSupportPopup()">
       X
      </button>
    </div>
    <div id="assistant-popup-body">
      <div class="messages" #scrollMe>
        <div *ngFor="let message of messages" class="message">
          <div [class]="message.type">
            {{ message.message }}
          </div>
        </div>
        <div
          *ngIf="loading"
          class="message"
          style="width: 100%; display: block"
        >
          <div [class]="'client'">Typing...</div>
        </div>
      </div>
    </div>
    <form id="assistant-popup-footer" [formGroup]="chatForm">
      <input
        formControlName="message"
        type="text"
        id="assistant-popup-input"
        placeholder="Type your message here..."
      />
      <button
        id="assistant-popup-submit-button"
        [disabled]="!chatForm.valid"
        (click)="sendMessage()"
      >
        Submit
      </button>
    </form>
  </div>
</div>
import { Component, ViewChild } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { MessageService } from '../service/api.service';

export interface Message {
  type: string;
  message: string;
}

@Component({
  selector: 'app-chat-support',
  templateUrl: './chat-support.component.html',
  styleUrls: ['./chat-support.component.scss'],
})
export class ChatSupportComponent {
  isOpen = false;
  loading = false;
  messages: Message[] = [];
  chatForm = new FormGroup({
    message: new FormControl('', [Validators.required]),
  });
  @ViewChild('scrollMe') private myScrollContainer: any;

  constructor(private messageService: MessageService) {
  }

  openSupportPopup() {
    this.isOpen = !this.isOpen;
  }

  sendMessage() {
    const sentMessage = this.chatForm.value.message!;
    this.loading = true;
    this.messages.push({
      type: 'user',
      message: sentMessage,
    });
    this.chatForm.reset();
    this.scrollToBottom();
    this.messageService.sendMessage(sentMessage).subscribe((response: any) => {
      for (const obj of response) {
        let value
        console.log(obj);
        if (obj.hasOwnProperty('text') ) {
          value = obj['text']
          this.pushMessage(value)

        }
        if (obj.hasOwnProperty('image') ) {
          value = obj['image']
          this.pushMessage(value)
        }
      }
      //MANIPULATION OF DATA TYPES OF RASA SUCH A IMAGE, TEXT, BUTTONS, ETC
    }
    , (error) => { console.log(error)});
  }

  pushMessage(message:string){

    console.log(message);
     setTimeout(() =>{this.messages.push({
      type: 'client',
      message: message,
    });
    this.loading = false;
    this.scrollToBottom();
  }, 150)
  }

  scrollToBottom() {
    setTimeout(() => {
      try {
        this.myScrollContainer.nativeElement.scrollTop =
          this.myScrollContainer.nativeElement.scrollHeight + 500;
      } catch (err) {}
    }, 150);
  }
}
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { APIService } from '../services/api.service';
import { MatSnackBar } from '@angular/material/snack-bar';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.scss']
})
export class RegisterComponent implements OnInit {

  registerFormGroup: FormGroup = this.fb.group({
    emailaddress: ['', [Validators.required, Validators.email]],
    password: ['', [Validators.required, Validators.minLength(6), Validators.maxLength(16)]],
  })

  constructor(private router: Router, private apiService: APIService, private fb: FormBuilder, private snackBar: MatSnackBar) { 

    
  }

  ngOnInit(): void {
  }

  RegisterUser(){

    if(this.registerFormGroup.valid)
    {
        this.apiService.RegisterUser(this.registerFormGroup.value).subscribe(() => {
        this.registerFormGroup.reset();
        this.router.navigate(['']).then((navigated: boolean) => {
          if(navigated) {
            this.snackBar.open(`Registered successfully`, 'X', {duration: 5000});
          }
       });
      })
    }

    // if(this.registerFormGroup.valid)
    // {
    //   this.apiService.RegisterUser(this.registerFormGroup.value).subscribe(() => {
    //     this.registerFormGroup.reset();
    //     this.router.navigate(['']).then((navigated: boolean) => {
    //       if(navigated) {
    //         this.snackBar.open(`Registered successfully`, 'X', {duration: 5000});
    //       }
    //    });
    //   }, (response: HttpErrorResponse) => {
    //     if (response.status === 403) {
    //       this.snackBar.open(response.error, 'X', {duration: 5000});
    //     }
    //     if (response.status === 500){
    //       this.snackBar.open(response.error, 'X', {duration: 5000});
    //     }
    //   })
    // }
  }

}
<div class="login-wrapper" fxLayout="row" fxLayoutAlign="center center">
    <mat-card class="box">
      <mat-card-header>
        <mat-card-title>Register</mat-card-title>
      </mat-card-header>
      <form class="form" [formGroup]="registerFormGroup">
        <mat-card-content>
          <mat-form-field class="full-width">
            <mat-label>Email Address</mat-label>
            <input matInput placeholder="Enter a valid Email address" formControlName="emailaddress">
          </mat-form-field>
          <mat-form-field class="full-width">
              <mat-label>Password</mat-label>
            <input type="password" matInput placeholder="Enter between 6 to 16 characters" formControlName="password">
          </mat-form-field>
        </mat-card-content>
        <button mat-stroked-button color="primary" class="btn-block" (click)="RegisterUser()">Register</button>
      </form>
    </mat-card>
  </div>
<div class="login-wrapper" fxLayout="row" fxLayoutAlign="center center">
    <mat-card class="box" *ngIf="!isLoading">
      <mat-card-header>
        <mat-card-title>Log in</mat-card-title>
      </mat-card-header>
      <form class="form" [formGroup]="loginFormGroup">
        <mat-card-content>
          <mat-form-field class="full-width">
            <mat-label>Username</mat-label>
            <input matInput placeholder="Enter the User's Email address" formControlName="emailaddress">
          </mat-form-field>
          <mat-form-field class="full-width">
            <mat-label>Password</mat-label>
            <input matInput type="password" placeholder="Enter the User's Password" formControlName="password">
          </mat-form-field>
        </mat-card-content>
        <button mat-stroked-button color="primary" class="btn-block" (click)="LoginUser()">Log in</button>
        <div>Don't have an account? Register <a [routerLink]="['../register']">here</a></div>
      </form>
    </mat-card>
    <mat-progress-spinner mode="indeterminate" value="50" *ngIf="isLoading">
    </mat-progress-spinner>
  </div>
import { Component, OnInit } from '@angular/core';
import { Restaurant } from 'src/app/models/restaurant.model';
import { ApiService } from 'src/app/services/api/api.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.page.html',
  styleUrls: ['./home.page.scss'],
})
export class HomePage implements OnInit {

  banners: any[] = [];
  restaurants: Restaurant[] = [];
  isLoading: boolean = false;

  constructor(
    private api: ApiService
  ) { }

  ngOnInit() {
    this.isLoading = true;
    setTimeout(() => {  
      this.banners = this.api.banners;
      this.restaurants = this.api.restaurants;
      this.isLoading = false;
    }, 3000);
    
  }

}
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
 import { IonicModule } from '@ionic/angular';
 import { Component, ViewChild } from '@angular/core';
 import { IonModal } from '@ionic/angular';
 import { OverlayEventDetail } from '@ionic/core/components';

@Component({
  selector: 'app-account',
  templateUrl: './account.page.html',
  styleUrls: ['./account.page.scss'],
  standalone: true,
  imports: [IonicModule, CommonModule, FormsModule],
  
})
export class AccountPage {
 
  @ViewChild(IonModal) modal!: IonModal;

  dishPrice: string = '';
  restaurantName!: string;
  dishName!: string;
  quantity!:string;
  orderHistory: any[] = [];
  userName: string = 'John Doe';
  userEmail: string = 'johndoe@gmail.com';
  userNumber: string = '012 345 6789';
  totalPrice: number =0;
  itemPrice: number =0;
  
  ionViewWillEnter() {
    // retrieve cart items from local storage
    this.orderHistory = JSON.parse(localStorage.getItem('paidList') ?? "paidList");
    const cartItems = JSON.parse(localStorage.getItem('paidList') ?? "[]");
    
    if (this.orderHistory != null) {
      this.orderHistory = cartItems;
      this.calculateTotalPrice();
    }
  };

  calculateTotalPrice() {
    let totalPrice = 0;
    let itemPrice = 0;

      for (let item of this.orderHistory) {
        itemPrice += item.dishPrice * item.quantity;
      }
      // add delivery fee to the total price
      totalPrice = itemPrice + 50;
      this.totalPrice = totalPrice;
      this.itemPrice = itemPrice;
    }

  cancel() {
    this.modal.dismiss(null, 'cancel');
  }

  async canDismiss(data?: any, role?: string) {
    return role !== 'gesture';
  }

  confirm() {
    this.modal.dismiss({name: this.userName, email: this.userEmail, number: this.userNumber}, 'confirm');
    this.modal   
  }

  onWillDismiss(event: Event) {
    const ev = event as CustomEvent<OverlayEventDetail<{name:string, email:string, number:string}>>;
    if (ev.detail.role === 'confirm') {
      if(ev.detail.data){
        this.userName = `${ev.detail.data.name}`;
        this.userEmail = `${ev.detail.data.email}`;
        this.userNumber = `${ev.detail.data.number}`;
      }
      else
      {
        console.log('undefined')
      }
    }

  }

  reOrderAddToCart(){
  // Retrieve the orderList from local storage
  const orderList = JSON.parse(localStorage.getItem('paidList') ?? '[]');

  // Store the orderList in the paidList array
  localStorage.setItem('orderList', JSON.stringify(orderList));

  // Clear the orderList array in local storage
  localStorage.setItem('paidList', JSON.stringify([]));

  setTimeout(() => {
    const orderCards = document.querySelectorAll('.orderHistory-card');
    orderCards.forEach(card => card.remove());
  }, 100);

  }

 
}

<div class="ion-page" #page>
<ion-content [fullscreen]="true" class="ion-padding">
  <ion-header>
    <ion-toolbar>
      <ion-title>Account</ion-title>
    </ion-toolbar>
  </ion-header>
        <ion-list>
          <ion-item> 
            <ion-label>{{userName}} <br>                
              <ion-text color="medium">
                <sub><ion-icon name="call"></ion-icon>{{userNumber}}</sub>
                <sub>  |  </sub>
                <sub><ion-icon name="mail"></ion-icon>{{userEmail}}</sub>
              </ion-text>
            </ion-label>
            <ion-button slot="end" fill="outline" size="small" id="open-modal" expand="block">Edit</ion-button>
          </ion-item>
        </ion-list>
        <ion-grid>
          <ion-row class="ion-text-center">
            <ion-col size="auto">
              <ion-icon style="padding-top: 12px;" aria-hidden="true" name="home" size="large"></ion-icon>
            </ion-col>
            <ion-col>
              <h3><ion-text>Manage Address</ion-text></h3>
            </ion-col>
            <ion-col size="auto">
              <ion-button fill="clear"><ion-icon size="large" name="chevron-forward-circle-outline"></ion-icon></ion-button>
            </ion-col>
          </ion-row>
        </ion-grid>

        <ion-modal trigger="open-modal" (willDismiss)="onWillDismiss($event)">
          <ng-template>
            <ion-header>
              <ion-toolbar>
                <ion-buttons slot="start">
                  <ion-button (click)="cancel()">Cancel</ion-button>
                </ion-buttons>
                <ion-title>Edit</ion-title>
                <ion-buttons slot="end">
                  <ion-button (click)="confirm()" [strong]="true">Confirm</ion-button>
                </ion-buttons>
              </ion-toolbar>
            </ion-header>
            <ion-content class="ion-padding">
              <ion-item>
                <ion-label position="stacked">Enter your name</ion-label>
                <ion-input type="text" placeholder="Your name"[(ngModel)] = "userName"></ion-input>
                <ion-label position="stacked">Enter your email</ion-label>
                <ion-input type="text" placeholder="Your email"[(ngModel)] = "userEmail"></ion-input>
                <ion-label position="stacked">Enter your number</ion-label>
                <ion-input type="text" placeholder="Your number"[(ngModel)] = "userNumber"></ion-input>
              </ion-item>
            </ion-content>
          </ng-template>
        </ion-modal>

  <ion-card>
    <ion-card-header color="primary">
      <ion-card-title>Order History</ion-card-title>
    </ion-card-header>
   <br>
    <ion-card-content  *ngFor="let item of orderHistory">
      <ion-list class="orderHistory-card">
        <ion-item>
          <h2><ion-label>{{ item.restaurantName }} </ion-label></h2>
        </ion-item>
        <ion-item>
          <ion-label>Dish: {{ item.dishName }}</ion-label>
        </ion-item>
        <ion-item>
          <ion-label>Quantity: {{ item.quantity }}</ion-label>
        </ion-item>
      </ion-list>
    </ion-card-content>
    <ion-card-content>
      <ion-text color="primary">
        <h1>Total: {{ totalPrice | currency :'ZAR':'symbol'}}</h1>
      </ion-text>
      <ion-text color="secondary">
        <sub>Includes delivery fee</sub>
      </ion-text>
    </ion-card-content>
  </ion-card>

  <ion-grid>
    <ion-row>
      <ion-col>
        <ion-button style="width: 100%;" fill="outline" size="small" (click)="reOrderAddToCart()">Reorder All</ion-button>
      </ion-col>
      <ion-col>
        <ion-button style="width: 100%;" fill="outline" size="small"  id="open-help-modal" expand="block">Need Help?</ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>

  <ion-modal #modal trigger="open-help-modal" [canDismiss]="canDismiss" [presentingElement]="page">
    <ng-template>
      <ion-header>
        <ion-toolbar>
          <ion-title>Modal</ion-title>
          <ion-buttons slot="end">
            <ion-button (click)="modal.dismiss()">Close</ion-button>
          </ion-buttons>
        </ion-toolbar>
      </ion-header>
      <ion-content class="ion-padding">
        <h1>
          Placing an order:
        </h1>
        <p>
          To place an order, simply search for the restaurant or cuisine you're interested in, browse their menu, and select the items you'd like to order. Once you're done, proceed to the checkout page and review your order details before submitting.
        </p>
        <h1>
          Making a payment:
        </h1>
        <p>
          We offer a variety of payment options, including credit/debit card, PayPal, and in-app wallet. Simply select your preferred payment method at checkout and follow the instructions to complete your transaction.
        </p>
        <h1>
          Changing delivery address:
        </h1>
        <p>
          If you need to change your delivery address after placing an order, please contact our support team as soon as possible. We'll do our best to accommodate your request, but please note that any changes made after the order has been dispatched may result in a delay or additional fee.
        </p>
        <h1>
          Changing user details:
        </h1>
        <p>
          To update your user details, including your name, email, phone number, or password, go to your account settings page and make the necessary changes. Please note that some details, such as your email or phone number, may be required for verification purposes and cannot be changed without additional steps.
        </p>
      </ion-content>
    </ng-template>
  </ion-modal>
</ion-content>
</div>



<div class="ion-page" #page>
<ion-content [fullscreen]="true" class="ion-padding">
  <ion-header>
    <ion-toolbar>
      <ion-title>Account</ion-title>
    </ion-toolbar>
  </ion-header>
        <ion-list>
          <ion-item> 
            <ion-label>{{userName}} <br>                
              <ion-text color="medium">
                <sub><ion-icon name="call"></ion-icon>{{userNumber}}</sub>
                <sub>  |  </sub>
                <sub><ion-icon name="mail"></ion-icon>{{userEmail}}</sub>
              </ion-text>
            </ion-label>
            <ion-button slot="end" fill="outline" size="small" id="open-modal" expand="block">Edit</ion-button>
          </ion-item>
        </ion-list>
        <ion-grid>
          <ion-row class="ion-text-center">
            <ion-col size="auto">
              <ion-icon style="padding-top: 12px;" aria-hidden="true" name="home" size="large"></ion-icon>
            </ion-col>
            <ion-col>
              <h3><ion-text>Manage Address</ion-text></h3>
            </ion-col>
            <ion-col size="auto">
              <ion-button fill="clear"><ion-icon size="large" name="chevron-forward-circle-outline"></ion-icon></ion-button>
            </ion-col>
          </ion-row>
        </ion-grid>

        <ion-modal trigger="open-modal" (willDismiss)="onWillDismiss($event)">
          <ng-template>
            <ion-header>
              <ion-toolbar>
                <ion-buttons slot="start">
                  <ion-button (click)="cancel()">Cancel</ion-button>
                </ion-buttons>
                <ion-title>Edit</ion-title>
                <ion-buttons slot="end">
                  <ion-button (click)="confirm()" [strong]="true">Confirm</ion-button>
                </ion-buttons>
              </ion-toolbar>
            </ion-header>
            <ion-content class="ion-padding">
              <ion-item>
                <ion-label position="stacked">Enter your name</ion-label>
                <ion-input type="text" placeholder="Your name"[(ngModel)] = "userName"></ion-input>
                <ion-label position="stacked">Enter your email</ion-label>
                <ion-input type="text" placeholder="Your email"[(ngModel)] = "userEmail"></ion-input>
                <ion-label position="stacked">Enter your number</ion-label>
                <ion-input type="text" placeholder="Your number"[(ngModel)] = "userNumber"></ion-input>
              </ion-item>
            </ion-content>
          </ng-template>
        </ion-modal>

  <ion-card>
    <ion-card-header color="primary">
      <ion-card-title>Order History</ion-card-title>
    </ion-card-header>
   <br>
    <ion-card-content  *ngFor="let item of orderHistory">
      <ion-list class="orderHistory-card">
        <ion-item>
          <h2><ion-label>{{ item.restaurantName }} </ion-label></h2>
        </ion-item>
        <ion-item>
          <ion-label>Dish: {{ item.dishName }}</ion-label>
        </ion-item>
        <ion-item>
          <ion-label>Quantity: {{ item.quantity }}</ion-label>
        </ion-item>
      </ion-list>
    </ion-card-content>
    <ion-card-content>
      <ion-text color="primary">
        <h1>Total: {{ totalPrice | currency :'ZAR':'symbol'}}</h1>
      </ion-text>
      <ion-text color="secondary">
        <sub>Includes delivery fee</sub>
      </ion-text>
    </ion-card-content>
  </ion-card>

  <ion-grid>
    <ion-row>
      <ion-col>
        <ion-button style="width: 100%;" fill="outline" size="small" (click)="reOrderAddToCart()">Reorder All</ion-button>
      </ion-col>
      <ion-col>
        <ion-button style="width: 100%;" fill="outline" size="small"  id="open-help-modal" expand="block">Need Help?</ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>

  <ion-modal #modal trigger="open-help-modal" [canDismiss]="canDismiss" [presentingElement]="page">
    <ng-template>
      <ion-header>
        <ion-toolbar>
          <ion-title>Modal</ion-title>
          <ion-buttons slot="end">
            <ion-button (click)="modal.dismiss()">Close</ion-button>
          </ion-buttons>
        </ion-toolbar>
      </ion-header>
      <ion-content class="ion-padding">
        <h1>
          Placing an order:
        </h1>
        <p>
          To place an order, simply search for the restaurant or cuisine you're interested in, browse their menu, and select the items you'd like to order. Once you're done, proceed to the checkout page and review your order details before submitting.
        </p>
        <h1>
          Making a payment:
        </h1>
        <p>
          We offer a variety of payment options, including credit/debit card, PayPal, and in-app wallet. Simply select your preferred payment method at checkout and follow the instructions to complete your transaction.
        </p>
        <h1>
          Changing delivery address:
        </h1>
        <p>
          If you need to change your delivery address after placing an order, please contact our support team as soon as possible. We'll do our best to accommodate your request, but please note that any changes made after the order has been dispatched may result in a delay or additional fee.
        </p>
        <h1>
          Changing user details:
        </h1>
        <p>
          To update your user details, including your name, email, phone number, or password, go to your account settings page and make the necessary changes. Please note that some details, such as your email or phone number, may be required for verification purposes and cannot be changed without additional steps.
        </p>
      </ion-content>
    </ng-template>
  </ion-modal>
</ion-content>
</div>



import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { Component } from '@angular/core';
import { ToastController } from '@ionic/angular';
import { HomePage } from '../home/home.page';

@Component({
  selector: 'app-cart',
  templateUrl: './cart.page.html',
  styleUrls: ['./cart.page.scss'],
  standalone: true,
  imports: [IonicModule, CommonModule, FormsModule],
  providers:[HomePage],
})
export class CartPage  {
  cartItems: any[] = [];
  deliveryInstructions: string = '';
  totalPrice: number = 0;
  itemPrice: number = 0;
  officeAddress: string = '123 Main St.';

  constructor(private toastController: ToastController, private homePage:HomePage) {}

 
  makePayment(){
  // Retrieve the orderList from local storage
  const orderList = JSON.parse(localStorage.getItem('orderList') ?? '[]');
  // Store the orderList in the paidList array
  localStorage.setItem('paidList', JSON.stringify(orderList));
  // Clear the orderList array in local storage
  localStorage.setItem('orderList', JSON.stringify([]));
    // Remove the order cards from the DOM after a short delay
    setTimeout(() => {
      const orderCards = document.querySelectorAll('.order-card');
      orderCards.forEach(card => card.remove());
    }, 100);
  };


  ionViewWillEnter() {
    // retrieve cart items from local storage
    const cartItems = JSON.parse(localStorage.getItem('orderList') ?? "[]");
    
    if (cartItems != null) {
      this.cartItems = cartItems;
      this.calculateTotalPrice();
    }
  }

  calculateTotalPrice() {
    let totalPrice = 0;
    let itemPrice = 0;

    console.log(this.cartItems);

      for (let item of this.cartItems) {
        itemPrice += item.dishPrice * item.quantity;
      }
      // add delivery fee to the total price
      totalPrice = itemPrice + 50;
      this.totalPrice = totalPrice;
      this.itemPrice = itemPrice;
      console.log(totalPrice)
    
    }

  async presentToast(position: 'middle') {
    const toast = await this.toastController.create({
      message: 'Payment Successful!',
      duration: 1500,
      position: position
    });
    await toast.present();
  }

  handlerMessage = '';

  public alertButtons = [
    {
      text: 'Cancel',
      role: 'cancel',
      handler: () => {  }
    },
    {
      text: 'OK',
      role: 'confirm',
      // I want to present a toast message when the user clicks OK 
      handler: () => {this.makePayment(); this.presentToast('middle'); this.ionViewWillEnter() }
    }
  ];

};

<ion-content [fullscreen]="true"  class="ion-padding">
  <ion-header>
    <ion-toolbar>
      <ion-title>Cart</ion-title>
    </ion-toolbar>
  </ion-header>

  <ion-card class="order-card" *ngFor="let item of cartItems">
    <ion-card-header color="primary">
      <ion-card-title>{{ item.restaurantName }}</ion-card-title>
    </ion-card-header>
    <br>
    <ion-card-content>
      <p>Dish: {{ item.dishName }}</p>
      <p>Quantity: {{ item.quantity }}</p>
      <p>Price: {{ item.dishPrice | currency :'ZAR':'symbol' }}</p>
    </ion-card-content>
  </ion-card>
  
  <ion-grid>
    <ion-row class="ion-text-center">
      <ion-col size="2">
        <ion-icon style="padding-top: 12px;" aria-hidden="true" name="home" size="large"></ion-icon>
      </ion-col>
      <ion-col style="padding-top: 13px;">
        <ion-row>
          Deliver to My Couch
        </ion-row>
        <ion-row>
          <ion-text color="medium"><sub>12 Main Street</sub></ion-text>
        </ion-row>
      </ion-col>
      <ion-col size="auto">
        <ion-button fill="clear"><ion-text color="danger" size="small">CHANGE</ion-text></ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>

  <ion-card>
   
    <ion-card-header color="primary">
     <ion-card-title> Cart details </ion-card-title>
    </ion-card-header>
  
    <ion-card-content>
      <ion-grid>
        <ion-row>
          <ion-col>Item Total:</ion-col>
          <ion-col>{{itemPrice | currency :'ZAR':'symbol'}}</ion-col>
        </ion-row>
        <ion-row>
          <ion-col>Delivery Fee:</ion-col>
          <ion-col>{{ 50 | currency :'ZAR':'symbol'}}</ion-col>
        </ion-row>
        <ion-row>
          <ion-col>Total Price:</ion-col>
          <ion-col>{{ totalPrice | currency :'ZAR':'symbol'}}</ion-col>
        </ion-row>
      </ion-grid> 
      
      <ion-button id="present-alert" expand="block" color="primary">Make Payment</ion-button> 
      <ion-toast class="custom-toast" position="middle" trigger="open-toast" message="Payment successful!" [duration]="3000" icon="checkmark-sharp"></ion-toast>
    </ion-card-content>
  </ion-card>


  <ion-alert
    trigger="present-alert"
    header="Confirm Payment"
    [buttons]="alertButtons"
  ></ion-alert>

</ion-content> 


<ion-content [fullscreen]="true"  class="ion-padding">
  <ion-header>
    <ion-toolbar>
      <ion-title>Cart</ion-title>
    </ion-toolbar>
  </ion-header>

  <ion-card class="order-card" *ngFor="let item of cartItems">
    <ion-card-header color="primary">
      <ion-card-title>{{ item.restaurantName }}</ion-card-title>
    </ion-card-header>
    <br>
    <ion-card-content>
      <p>Dish: {{ item.dishName }}</p>
      <p>Quantity: {{ item.quantity }}</p>
      <p>Price: {{ item.dishPrice | currency :'ZAR':'symbol' }}</p>
    </ion-card-content>
  </ion-card>
  
  <ion-grid>
    <ion-row class="ion-text-center">
      <ion-col size="2">
        <ion-icon style="padding-top: 12px;" aria-hidden="true" name="home" size="large"></ion-icon>
      </ion-col>
      <ion-col style="padding-top: 13px;">
        <ion-row>
          Deliver to My Couch
        </ion-row>
        <ion-row>
          <ion-text color="medium"><sub>12 Main Street</sub></ion-text>
        </ion-row>
      </ion-col>
      <ion-col size="auto">
        <ion-button fill="clear"><ion-text color="danger" size="small">CHANGE</ion-text></ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>

  <ion-card>
   
    <ion-card-header color="primary">
     <ion-card-title> Cart details </ion-card-title>
    </ion-card-header>
  
    <ion-card-content>
      <ion-grid>
        <ion-row>
          <ion-col>Item Total:</ion-col>
          <ion-col>{{itemPrice | currency :'ZAR':'symbol'}}</ion-col>
        </ion-row>
        <ion-row>
          <ion-col>Delivery Fee:</ion-col>
          <ion-col>{{ 50 | currency :'ZAR':'symbol'}}</ion-col>
        </ion-row>
        <ion-row>
          <ion-col>Total Price:</ion-col>
          <ion-col>{{ totalPrice | currency :'ZAR':'symbol'}}</ion-col>
        </ion-row>
      </ion-grid> 
      
      <ion-button id="present-alert" expand="block" color="primary">Make Payment</ion-button> 
      <ion-toast class="custom-toast" position="middle" trigger="open-toast" message="Payment successful!" [duration]="3000" icon="checkmark-sharp"></ion-toast>
    </ion-card-content>
  </ion-card>


  <ion-alert
    trigger="present-alert"
    header="Confirm Payment"
    [buttons]="alertButtons"
  ></ion-alert>

</ion-content> 


import { Component } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
  standalone: true,
  imports: [IonicModule, CommonModule],
})
export class HomePage {
 
  restaurantList = [
    {
      name: "KFC",
      dish: "KFC Bucket",
      rating: 3.9,
      distance: "4km",
      price: 54.90,
      image: "assets/KFC.png",
      topDish: "Fast Food",
      orderQuantity: 0,
    },
    {
      name: "Burger King",
      dish: "Whopper",
      rating: 3.7,
      distance: "6.7km",
      price: 59.95,
      image: "assets/BK.png",
      topDish: "Fast Food",
      orderQuantity: 0,
    },
    {
      name: "Pizza Hut",
      dish: "My Box",
      rating: 4.0,
      distance: "7.1km",
      price: 44.90,
      image: "assets/PH.png",
      topDish: "Fast Food",
      orderQuantity: 0,
    },
    {
      name: "McDonalds",
      dish: "Big Mac",
      rating: 4.3,
      distance: "3.2km",
      price: 49.90,
      image: "assets/Mac.png",
      topDish: "Fast Food",
      orderQuantity: 0,
    },
  ];
  

  addToCart(restaurant: { 
    name: string, 
    dish: string, 
    rating: number, 
    distance: string, 
    price: number, 
    topDish: string, 
    orderQuantity: number }) {
    
    const orderList = JSON.parse(localStorage.getItem('orderList')??'[]');
    const orderIndex = orderList.findIndex((order: {restaurantName:string;})=> order.restaurantName === restaurant.name );

    if (orderIndex === -1) {
      orderList.push({
        dishPrice: restaurant.price,
        restaurantName: restaurant.name,
        dishName: restaurant.dish,
        quantity: 1,
      });
    } else {
      orderList[orderIndex].quantity++;
    }
    localStorage.setItem('orderList', JSON.stringify(orderList));
  }

  reOrderAddToCart(restaurant: { 
    name: string, 
    dish: string, 
    rating: number, 
    distance: string, 
    price: number, 
    topDish: string, 
    orderQuantity: number }) {
    
    const paidorderList = JSON.parse(localStorage.getItem('paidList')??'[]');
    console.log(paidorderList)

    const orderIndex = paidorderList.findIndex((order: {name:string;})=> order.name === restaurant.name );
    console.log(orderIndex)

    if (orderIndex === -1) {
      paidorderList.push({
        dishPrice: restaurant.price,
        restaurantName: restaurant.name,
        dishName: restaurant.dish,
        quantity: 1,
      });
    } else {
      paidorderList[orderIndex].quantity++;
    }
    localStorage.setItem('orderList', JSON.stringify(paidorderList));
  }

  
}
<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Home
    </ion-title>
  </ion-toolbar>
</ion-header>


<ion-content [fullscreen]="true">
  <!-- ------------------ -->
  <ion-searchbar (ionInput)="search($event)" animated="true" placeholder="Search"></ion-searchbar>
      <ion-list  *ngFor="let data of restaurantList">
        <ion-item lines="none" color="light">
          <ion-thumbnail slot="start">
            <img alt="Silhouette of mountains" src={{data.image}}/>
          </ion-thumbnail>
          <ion-grid>
            <ion-row>
              <ion-col>
                <ion-text>
                  {{data.name}}
                </ion-text>
              </ion-col>
            </ion-row>

            <ion-row>
              <ion-col>
                <ion-text color="medium">
                  {{data.type}}
                </ion-text>
              </ion-col>
            </ion-row>

            <ion-row>
              <ion-col>
                <ion-icon name="star"></ion-icon> {{data.rating}}
              </ion-col>
              <ion-col>
                R{{data.price}}
              </ion-col>
            </ion-row>

            <ion-row>
              <ion-col>
                <ion-icon name="car"></ion-icon> <ion-text color="danger"> {{data.distance}}</ion-text>
              </ion-col>
            </ion-row>
            <ion-row>
              <ion-button style="width: 100%">Add to cart</ion-button> 
            </ion-row>
          </ion-grid>
        </ion-item>
      </ion-list>
</ion-content>
<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Home
    </ion-title>
  </ion-toolbar>
</ion-header>


<ion-content [fullscreen]="true">
  <!-- ------------------ -->
  <ion-searchbar (ionInput)="search($event)" animated="true" placeholder="Search"></ion-searchbar>
      <ion-list  *ngFor="let data of restaurantList">
        <ion-item lines="none" color="light">
          <ion-thumbnail slot="start">
            <img alt="Silhouette of mountains" src={{data.image}}/>
          </ion-thumbnail>
          <ion-grid>
            <ion-row>
              <ion-col>
                <ion-text>
                  {{data.name}}
                </ion-text>
              </ion-col>
            </ion-row>

            <ion-row>
              <ion-col>
                <ion-text color="medium">
                  {{data.type}}
                </ion-text>
              </ion-col>
            </ion-row>

            <ion-row>
              <ion-col>
                <ion-icon name="star"></ion-icon> {{data.rating}}
              </ion-col>
              <ion-col>
                R{{data.price}}
              </ion-col>
            </ion-row>

            <ion-row>
              <ion-col>
                <ion-icon name="car"></ion-icon> <ion-text color="danger"> {{data.distance}}</ion-text>
              </ion-col>
            </ion-row>
            <ion-row>
              <ion-button style="width: 100%">Add to cart</ion-button> 
            </ion-row>
          </ion-grid>
        </ion-item>
      </ion-list>
</ion-content>
# Installing Rosetta
/usr/sbin/softwareupdate --install-rosetta --agree-to-license

# Install NVM
# https://github.com/nvm-sh/nvm#install--update-script
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash

# Installing Node 14 by NVM
arch
# >>> arm64
arch -x86_64 zsh
arch
# >>> i386
nvm install 14
nvm use 14
White label trust wallet clone app is a handy solution for businesses unwilling to build a wallet from scratch. It can also be helpful for businesses that specialize in a specific domain but lack it from a technical perspective. Many white-label trust wallet like crypto wallets are flexible and can be customized to the requirements of the businesses. Overall, white-label crypto wallets offer the following benefits to businesses:

Low cost
Lesser time
Instant deployment
Advanced features

Businesses wanting to develop crypto wallets can either build one or utilize a white-label wallet. Leveraging a white-label trust wallet like wallet can cut down your extra expenses and save a lot of your time. Choosing a perfect white-label crypto wallet can help enhance your customer loyalty and acquire more customers.
The aim of crypto copy trading is for the newbie trader to have the same trades or copy the position as the trader they are copying. When you are copying the trade, you don’t receive the layout of the trader’s technique rather you will be following their trades blindly. 

The newbie traders who are just initiating their crypto trading journey may choose the finest crypto copy trading platforms to execute buy and sell orders at any time. If you want to start your own Crypto copy trading platform, Maticz offers you innovative blockchain development solutions that include crypto exchange, copy trading, margin trading, derivatives, and more.,

Get more info via,

Email: sales@maticz.com
Whatsapp: +91 93845 87998
Telegram: @Maticzofficial 
An Escrow service to endure a Bitcoin payment is a perfect idea when transacting with an untrusted party. Bitcoin Escrow script covers sellers from fraudulent buyers by requiring the Bitcoin to be deposited upfront. Also, buyers are protected if the seller turns out to be a scammer and doesn't deliver the goods. In the event of such a dispute, the escrow service will act as the mediator and define who should ultimately acquire the Bitcoin funds.
<p>{{ lesson?.description | replaceHtmlTags }}</p>
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'replaceHtmlTags' })
export class ReplaceHtmlTagsPipe implements PipeTransform {
  transform(html: string): string {
    return html.replace(/<\/?[^>]+(>|$)/g, '');
  }
}
@NgModule({
  declarations: [ReplaceHtmlTagsPipe],
  // ...
})
export class AppModule { }
As more people start using and investing in crypto, having a safe crypto wallet to protect your assets is essential. There are many crypto wallets in the market, but not all are made equal. The most repeatedly used is Trust Wallet. Want to start your own crypto wallet similar to trustwallet, then I would like to suggest Maticz's Trustwallet clone script integrated with elite features and functionalities that attain your business to the next level.

> https://maticz.com/trust-wallet-clone-app
Crypto Exchange Business is making the fastest turnover of the decade in hours. They tend to be the revolution that people expect and have become an exciting trend in this era. Furthermore, they are going to be the future and assist you to achieve the target that you are trying to achieve. Also, you can start your business and develop a crypto exchange at an affordable price and see the result. 

This Crypto Exchange business is the future and you could be leading the charge. However, ensure to create a profitable crypto exchange platform and become an entrepreneur. The revenue streams are huge, and you are the trendsetter in the future by becoming a successful entrepreneur.  

Are you interested to know about other crypto business ideas? then check this >> https://maticz.com/cryptocurrency-business-ideas
hello
Hello! How may I assist you today?





  updateQuyTrinhKySoToBehaviorSubject(id : number | null)
  {
    //const danhSachBuocQuyTrinhKySo = this.danhSachBuocQuyTrinhKySo$.getValue();

    const danhSachBuocQuyTrinhKySo : IBuocQuyTrinhKySoModel[] = [];
    const danhSachVaiTroKySo : IVaiTroBuocKyModel[] = [];


    this.getQuyTrinhKySo(id)
    .pipe(map((response : IResponseBaseModel<IRequestCreateQuyTrinhKySoModel>) => {
      debugger
      if(response.Success)
      {
        if((response.Result?.DanhSachBuocQuyTrinhKySoModel?.length ?? 0) > 0)
        {
          response.Result?.DanhSachBuocQuyTrinhKySoModel?.forEach((itemBuocQuyTrinh) => {
            debugger
            const itemBuocQuyTrinhKySo : IBuocQuyTrinhKySoModel = Object.assign(itemBuocQuyTrinh);

            danhSachBuocQuyTrinhKySo.push(itemBuocQuyTrinhKySo);

            if((itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel?.length ?? 0) > 0)
            {
              itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel?.forEach((itemVaiTro) => {
                debugger
                const itemVaiTroBuocKy : IVaiTroBuocKyModel = Object.assign(itemVaiTro);

                danhSachVaiTroKySo.push(itemVaiTroBuocKy);

              })
            }

          })

        }

      }

    }))
    .subscribe((result : any) => {
      debugger
      this.danhSachBuocQuyTrinhKySo$.next(danhSachBuocQuyTrinhKySo);
      this.danhSachVaiTroBuocKySo$.next(danhSachVaiTroKySo);

    })
  }
This is a TypeScript function that updates the values of two BehaviorSubjects (danhSachBuocQuyTrinhKySo$ and danhSachVaiTroBuocKySo$) based on the id parameter passed to the function. Here's a breakdown of the code:

id : number | null is the parameter for the function. It can be either a number or null.
const danhSachBuocQuyTrinhKySo : IBuocQuyTrinhKySoModel[] = []; initializes an empty array of type IBuocQuyTrinhKySoModel[].
const danhSachVaiTroKySo : IVaiTroBuocKyModel[] = []; initializes an empty array of type IVaiTroBuocKyModel[].
this.getQuyTrinhKySo(id) calls the getQuyTrinhKySo method and passes id as a parameter.
.pipe(map((response : IResponseBaseModel<IRequestCreateQuyTrinhKySoModel>) => { uses RxJS operators to manipulate the data emitted by the getQuyTrinhKySo method. It takes in a response object of type IResponseBaseModel<IRequestCreateQuyTrinhKySoModel> and returns a modified response object.
debugger is a statement that helps developers debug code by setting breakpoints.
if(response.Success) checks if the response is successful.
if((response.Result?.DanhSachBuocQuyTrinhKySoModel?.length ?? 0) > 0) checks if there are any items in the DanhSachBuocQuyTrinhKySoModel array of the response object.
response.Result?.DanhSachBuocQuyTrinhKySoModel?.forEach((itemBuocQuyTrinh) => { loops through each item in the DanhSachBuocQuyTrinhKySoModel array.
const itemBuocQuyTrinhKySo : IBuocQuyTrinhKySoModel = Object.assign(itemBuocQuyTrinh); creates a new IBuocQuyTrinhKySoModel object and assigns the values from the current itemBuocQuyTrinh object.
danhSachBuocQuyTrinhKySo.push(itemBuocQuyTrinhKySo); adds the new itemBuocQuyTrinhKySo object to the danhSachBuocQuyTrinhKySo array.
if((itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel?.length ?? 0) > 0) checks if there are any items in the DanhSachVaiTroBuocKyModel array of the current itemBuocQuyTrinh object.
itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel?.forEach((itemVaiTro) => { loops through each item in the DanhSachVaiTroBuocKyModel array.
const itemVaiTroBuocKy : IVaiTroBuocKyModel = Object.assign(itemVaiTro); creates a new IVaiTroBuocKyModel object and assigns the values from the current itemVaiTro object.
danhSachVaiTroKySo.push(itemVaiTroBuocKy); adds the new itemVaiTroBuocKy object to




help me improve the code
Sure! Here are a few suggestions to improve the code:

Use destructuring to simplify the code
Instead of using response.Result?.DanhSachBuocQuyTrinhKySoModel and response.Result?.DanhSachBuocQuyTrinhKySoModel?.length, you can use destructuring to simplify the code:

rust
Copy code
const { DanhSachBuocQuyTrinhKySoModel = [] } = response.Result || {};
const hasBuocQuyTrinhKySo = DanhSachBuocQuyTrinhKySoModel.length > 0;
This will make the code more readable and reduce the number of lines.

Use Array.map() to simplify iteration
Instead of using forEach() to iterate over the DanhSachBuocQuyTrinhKySoModel array, you can use Array.map() to simplify the code:

javascript
Copy code
const danhSachBuocQuyTrinhKySo = DanhSachBuocQuyTrinhKySoModel.map(itemBuocQuyTrinh => {
  const itemBuocQuyTrinhKySo : IBuocQuyTrinhKySoModel = Object.assign(itemBuocQuyTrinh);

  if ((itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel?.length ?? 0) > 0) {
    const danhSachVaiTroKySo = itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel.map(itemVaiTro => Object.assign(itemVaiTro));

    danhSachVaiTroBuocKySo.push(...danhSachVaiTroKySo);
  }

  return itemBuocQuyTrinhKySo;
});

This will also reduce the number of lines and make the code more readable.

Use spread operator to add elements to an array
Instead of using push() to add elements to an array, you can use the spread operator to simplify the code:

scss
Copy code
danhSachVaiTroBuocKySo.push(...danhSachVaiTroKySo);
This will add all elements of danhSachVaiTroKySo to danhSachVaiTroBuocKySo.

Here is the updated code:

typescript
Copy code
updateQuyTrinhKySoToBehaviorSubject(id: number | null) {
  const danhSachBuocQuyTrinhKySo: IBuocQuyTrinhKySoModel[] = [];
  const danhSachVaiTroBuocKySo: IVaiTroBuocKyModel[] = [];

  this.getQuyTrinhKySo(id).pipe(
    map((response: IResponseBaseModel<IRequestCreateQuyTrinhKySoModel>) => {
      const { DanhSachBuocQuyTrinhKySoModel = [] } = response.Result || {};
      const hasBuocQuyTrinhKySo = DanhSachBuocQuyTrinhKySoModel.length > 0;

      if (response.Success && hasBuocQuyTrinhKySo) {
        danhSachBuocQuyTrinhKySo = DanhSachBuocQuyTrinhKySoModel.map(itemBuocQuyTrinh => {
          const itemBuocQuyTrinhKySo: IBuocQuyTrinhKySoModel = Object.assign(itemBuocQuyTrinh);

          if ((itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel?.length ?? 0) > 





is there any other way to updates the values of two BehaviorSubjects ?
Yes, there are other ways to update the values of two BehaviorSubjects. One way is to use the combineLatest operator from RxJS. This operator allows you to combine the latest values from multiple observables into a single observable.

Here is an example of how you can use the combineLatest operator to update two BehaviorSubjects:

javascript
Copy code
import { combineLatest } from 'rxjs';

// Combine the latest values from the two BehaviorSubjects
const combined$ = combineLatest([
  this.danhSachBuocQuyTrinhKySo$,
  this.danhSachVaiTroBuocKySo$
]);

// Subscribe to the combined observable and update the values of the two BehaviorSubjects
combined$.subscribe(([danhSachBuocQuyTrinhKySo, danhSachVaiTroBuocKySo]) => {
  this.danhSachBuocQuyTrinhKySo$.next(danhSachBuocQuyTrinhKySo);
  this.danhSachVaiTroBuocKySo$.next(danhSachVaiTroBuocKySo);
});
In this example, we create a new observable called combined$ using the combineLatest operator. We pass in an array of observables to combine, which includes the two BehaviorSubjects we want to update.

We then subscribe to the combined$ observable, which emits an array of the latest values from the two BehaviorSubjects. We use array destructuring to get the values of the two BehaviorSubjects from the emitted array, and then update the values of the BehaviorSubjects using the next method.

Using the combineLatest operator can make your code more concise and easier to read, especially if you need to combine the latest values from multiple observables.






Combine with the above method
Sure! Here is an example of how you can combine the above method with the combineLatest operator:

typescript
Copy code
import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';

updateQuyTrinhKySoToBehaviorSubject(id: number | null) {
  const danhSachBuocQuyTrinhKySo$ = this.getQuyTrinhKySo(id).pipe(
    map((response: IResponseBaseModel<IRequestCreateQuyTrinhKySoModel>) => {
      if (response.Success && response.Result?.DanhSachBuocQuyTrinhKySoModel?.length) {
        return response.Result.DanhSachBuocQuyTrinhKySoModel.map((itemBuocQuyTrinh) => {
          const itemBuocQuyTrinhKySo: IBuocQuyTrinhKySoModel = Object.assign({}, itemBuocQuyTrinh);

          if (itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel?.length) {
            itemBuocQuyTrinhKySo.DanhSachVaiTroBuocKyModel = itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel.map((itemVaiTro) => {
              return Object.assign({}, itemVaiTro);
            });
          }

          return itemBuocQuyTrinhKySo;
        });
      } else {
        return [];
      }
    })
  );

  const danhSachVaiTroBuocKySo$ = danhSachBuocQuyTrinhKySo$.pipe(
    map((danhSachBuocQuyTrinhKySo) => {
      const danhSachVaiTroKySo = danhSachBuocQuyTrinhKySo.reduce((accumulator, itemBuocQuyTrinh) => {
        if (itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel?.length) {
          const vaiTroKySo = itemBuocQuyTrinh.DanhSachVaiTroBuocKyModel.map((itemVaiTro) => {
            return Object.assign({}, itemVaiTro);
          });
          return accumulator.concat(vaiTroKySo);
        } else {
          return accumulator;
        }
      }, []);
      return danhSachVaiTroKySo;
    })
  );

  const combined$ = combineLatest([danhSachBuocQuyTrinhKySo$, danhSachVaiTroBuocKySo$]);

  combined$.subscribe(([danhSachBuocQuyTrinhKySo, danhSachVaiTroBuocKySo]) => {
    this.danhSachBuocQuyTrinhKySo$.next(danhSachBuocQuyTrinhKySo);
    this.danhSachVaiTroBuocKySo$.next(danhSachVaiTroBuocKySo);
  });
}
In this updated code, we first create the danhSachBuocQuyTrinhKySo$ and danhSachVaiTroBuocKySo$ observables using the pipe operator and the map operator. These observables are created in the same way as in the original code.

We then create a new observable called combined$ using the combineLatest operator. We pass in an array of observables to combine, which includes danhSachBuocQuyTrinhKySo$ and danhSachVaiTroBuocKySo$.

We then subscribe to the `combined$
Sure! Here's a more complete example that demonstrates how to bind a hidden field to a component and update its value based on the value of another form field:

HTML template:

html
Copy code
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <div>
    <label>First Name: <input type="text" formControlName="firstName"></label>
  </div>
  <div>
    <label>Last Name: <input type="text" formControlName="lastName"></label>
  </div>
  <div>
    <label>Email Address: <input type="email" formControlName="email"></label>
  </div>
  <div>
    <label>Phone Number: <input type="text" formControlName="phoneNumber"></label>
  </div>
  <div>
    <input type="hidden" name="fullName" formControlName="fullName" [hidden]="!myForm.controls['fullName'].value">
    <p *ngIf="myForm.controls['fullName'].value">Full Name: {{ myForm.controls['fullName'].value }}</p>
  </div>
  <button type="submit">Submit</button>
</form>
Component:

typescript
Copy code
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponent {

  myForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.myForm = this.fb.group({
      firstName: ['', Validators.required],
      lastName: ['', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      phoneNumber: ['', Validators.required],
      fullName: ['']
    });

    // Listen for changes to the 'firstName', 'lastName', 'email', and 'phoneNumber' controls
    this.myForm.controls['firstName'].valueChanges.subscribe(value => {
      this.updateFullName();
    });
    this.myForm.controls['lastName'].valueChanges.subscribe(value => {
      this.updateFullName();
    });
    this.myForm.controls['email'].valueChanges.subscribe(value => {
      this.updateFullName();
    });
    this.myForm.controls['phoneNumber'].valueChanges.subscribe(value => {
      this.updateFullName();
    });
  }

  onSubmit() {
    console.log(this.myForm.value);
  }

  private updateFullName() {
    // Concatenate the values of the 'firstName', 'lastName', 'email', and 'phoneNumber' controls
    const fullName = `${this.myForm.controls['firstName'].value} ${this.myForm.controls['lastName'].value} (${this.myForm.controls['email'].value}, ${this.myForm.controls['phoneNumber'].value})`;

    // Update the value of the hidden field
    this.myForm.controls['fullName'].setValue(fullName);
  }

}
In this example, we added subscriptions to the valueChanges observables of the 'firstName', 'lastName', 'email', and 'phoneNumber' controls that call a private updateFullName() method. This method concatenates the values of these controls and sets the value of the hidden field (fullName) based on the concatenated value.

We also added an *ngIf directive to the HTML template to conditionally show the full name when the value of the hidden field is truthy.

I hope this helps! Let me know if you have any further questions.





any way to do that ?
Yes, there are multiple ways to achieve this behavior in Angular. One way is to use the (ngModelChange) directive on the input field that triggers the update, and then update the value of the hidden field in the component. Here's an example:

HTML template:

html
Copy code
<input type="text" [(ngModel)]="firstName" (ngModelChange)="updateFullName()">
<input type="hidden" [value]="fullName">
<p *ngIf="fullName">Full Name: {{ fullName }}</p>
Component:

typescript
Copy code
import { Component } from '@angular/core';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponent {

  firstName: string = '';
  lastName: string = '';
  email: string = '';
  phoneNumber: string = '';
  fullName: string = '';

  updateFullName() {
    // Concatenate the values of the 'firstName', 'lastName', 'email', and 'phoneNumber' fields
    this.fullName = `${this.firstName} ${this.lastName} (${this.email}, ${this.phoneNumber})`;
  }

}
In this example, we used two-way data binding with [(ngModel)] to bind the value of the firstName field to a variable in the component. We also added the (ngModelChange) directive to trigger the updateFullName() method in the component whenever the value of firstName changes. The updateFullName() method concatenates the values of the fields and sets the value of the fullName variable in the component. Finally, we used the [value] directive to bind the value of the hidden field to the fullName variable, and added an *ngIf directive to conditionally show the full name when the fullName variable is truthy.

I hope this helps! Let me know if you have any further questions.





wich one is the popular chose ?
The approach I mentioned earlier, which uses two-way data binding with (ngModel) and (ngModelChange), is a popular choice for binding hidden fields in Angular. However, there are other ways to achieve the same behavior, such as using reactive forms and updating the value of the hidden field using the patchValue() or setValue() methods of the form control. The choice ultimately depends on your specific use case and preferences.
In Angular, there are several ways to pass data between two components. Here are some common methods:

Input and Output Properties:
Input properties are used to pass data from a parent component to a child component, and Output properties are used to emit events from a child component to a parent component.
For example, in the parent component, you can define an input property and bind it to a property on the child component. And in the child component, you can define an output property and emit an event when the data changes. Here's an example:

Parent component:

kotlin
Copy code
@Component({
  selector: 'app-parent',
  template: `
    <app-child [message]="parentMessage" (messageEvent)="receiveMessage($event)"></app-child>
  `,
})
export class ParentComponent {
  parentMessage = "Message from parent";

  receiveMessage($event) {
    console.log($event);
  }
}
Child component:

kotlin
Copy code
@Component({
  selector: 'app-child',
  template: `
    {{ message }}
    <button (click)="sendMessage()">Send Message</button>
  `,
})
export class ChildComponent {
  @Input() message: string;
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage() {
    this.messageEvent.emit("Message from child");
  }
}
Service:
You can also use a service to pass data between components. In this approach, you create a service that holds the data and inject the service into the components that need it. Here's an example:
Service:

typescript
Copy code
@Injectable({ providedIn: 'root' })
export class DataService {
  private messageSource = new BehaviorSubject<string>("default message");
  currentMessage = this.messageSource.asObservable();

  changeMessage(message: string) {
    this.messageSource.next(message);
  }
}
Parent component:

typescript
Copy code
@Component({
  selector: 'app-parent',
  template: `
    {{ message }}
    <button (click)="newMessage()">New Message</button>
  `,
})
export class ParentComponent {
  message: string;

  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.dataService.currentMessage.subscribe(message => this.message = message);
  }

  newMessage() {
    this.dataService.changeMessage("New message from parent");
  }
}
Child component:

typescript
Copy code
@Component({
  selector: 'app-child',
  template: `
    {{ message }}
  `,
})
export class ChildComponent {
  message: string;

  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.dataService.currentMessage.subscribe(message => this.message = message);
  }
}
In the example above, the DataService has a private BehaviorSubject that holds the message, and exposes an Observable called currentMessage that can be subscribed to in the components. The parent component calls changeMessage() on the service to update the message, and the child component automatically receives the updated message through the subscription to currentMessage.

There are other ways to pass data between components, but these are the most common approaches in Angular.
@Component //Every component start with component decorator, Angular allows us to pass in a object based on how the component behaves
ng serve open | ng s -o //Opening server in localhost angular
ng generate component component-name | ng g c component-name //create a new component
*ng //always add asterisks at the beginning
[class.some-css-class] //class binding, add and remove a CSS class conditionally
ng generate service hero //share information among classes that don't know each other
ng serve open | ng s -o //Opening server in localhost angular
ng generate component component-name | ng g c component-name //create a new component
*ng //always add asterisks at the beginning
[class.some-css-class] //class binding, add and remove a CSS class conditionally
ng generate service hero //share information among classes that don't know each other
//problem
@Component({
  template: `
    <p>Welcome {{ fullName() }}!</p>
`
})
export class PersonComponent {  
@Input() person: { firstName: string, lastName: string };  constructor() { }  
fullName() {
    return this.person.firstName + ' ' + this.person.lastName
  }  

}

//solusion
@Component({
  template: `
    <p>Welcome {{  name | nameToString  }}!</p>
`
})
export class PersonComponent {
@Input() person: { firstName: string, lastName: string };  constructor() { }  

}


import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'nameToString'
})
export class IdPathPipe implements PipeTransform {
  transform(value): string {
    return value.firstName = value.lastName
request = this.http.get('/users').pipe(
  tap(()=> setContent('Resposta da API'))
)
stopRequest = btnStopRequest$.pipe(
  tap(()=> setContent('Requisicao cancelada'))
)

btnRequest

users$ = this.http.get<User[]>(url).pipe(
	tap(console.log),
  	catchError(this.handleError)
);

private handleError(err: HttpErrorResponse): Observable<never>{
  let errorMessage = `An error occurred: ${err.error.message}`;
  console.error(err);
  return throwError(() => errorMessage);
}
import { fromEvent, delayWhen, interval, of, Subject } from 'rxjs';

const sourceSebjec = new Subject<boolean>();
const sourceAction$ = sourceSebjec.asObservable();

fromEvent(document, 'click').subscribe({
  next: (x) => {
    console.log('CLik next: .. iniciou souce', x);
    sourceSebjec.next(false);
  },
  error: (x) => console.log('Clik erro:', x),
  complete: () => console.log('Clik complete'),
});

sourceAction$.pipe(delayWhen((v) => (v ? interval(2000) : of(0)))).subscribe({
  next: (x) => {
    console.log('Souce next:', x);
  },
  error: (x) => console.log('Souce erro:', x),
  complete: () => console.log('Souce complete'),
});
import { Injectable } from '@angular/core';
import { HttpErrorResponse, HttpClient } from '@angular/common/http';

import { Observable, throwError } from 'rxjs';
import { catchError, shareReplay } from 'rxjs/operators';

import { Product } from './models/product.model';

@Injectable({
  providedIn: 'root'
})
export class ProductsService {
  private const API = 'api/products';

  allProducts$ = this.http.get<Product[]>(this.API).pipe(
    shareReplay(1),
    catchError(this.handleError),
    );

  constructor(private http: HttpClient){}

  private handleError(err: HttpErrorResponse): Observable<never>{
    let errorMessage: string;
    if(err.error instanceof ErrorEvent){
      errorMessage = `Um error ocorreu: ${err.error.message}`;
    }else{
      errorMessage = `Servidor retornou codigo ${err.status}: ${err.message}`;
    }
    console.warn(err);
    return throwError(() => errorMessage)
  }

}
// html
    <ng-container *ngIf="vm$ | async as vm">
      <p *ngIf="vm.user; else userLoading">
      	Welcome back {{ vm.user }}
	  </p>

      <ng-template #userLoading>
        <p>Loading...</p>
        <p *ngIf="vm.userError">There was an error: {{ vm.userError }}</p>
      </ng-template>
    </ng-container>

// component
  user$ = this.userService.userErrored$.pipe(
    startWith(null),
    catchError(() => EMPTY)
  );
  userError$ = this.userService.userErrored$.pipe(
    ignoreElements(),
    startWith(null),
    catchError((err) => of(err))
  );

  vm$ = combineLatest([this.user$,this.userError$]).pipe(
    map(([user, userError]) => ({user, userError}));
  dataSource$ = this.dataSourceAction$.pipe(
    startWith([]),
    switchMap(() => {
      this.isLoadingResultsSubject.next(true);
      return this.getProduct(1).pipe(catchError(() => of(null)))
    }),
    map( data => {
      this.isLoadingResultsSubject.next(false);
      if(data === null) return []
      return data;
    }),);
https://danielk.tech/pt-br/como-ter-uma-nova-tentativa-de-requisicao-http-no-angular-varios-codigos-como-exemplo
const { fromEvent } = rxjs;
const { switchMap, takeUntil, map } = rxjs.operators;

const card = document.querySelector('.card');

const mouseDown$ = fromEvent(card,'mousedown');
const mouseUp$ = fromEvent(document, 'mouseup');
const mouseMove$ = fromEvent(document, 'mousemove');
const dragAndDrop$ = mouseDown$.pipe(
  map(e => ({})),
  switchMap( start => mouseMove$.pipe(
    takeUntil(mouseUp$)
  ))
);
dragAndDrop$.subscribe(v => console.log(v))
    private _categoryId: string;
    
    @Input() set categoryId(value: string) {
    
       this._categoryId = value;
       this.doSomething(this._categoryId);
    
    }
    
    get categoryId(): string {
    
        return this._categoryId;
    
    }
// usage
loadGame(): void {
  this.games = []
  this.loadHandler.start()
  this.http.get<Game[]>.get(this.url).subscribe(
    games => {
      this.loadHandler.finish();
      this.games = games;
    })
}

// service
export class LoadHandler {
  private _isLoading$ = new BehaviorSubject(false);
  isLoading$: Observable<boolean> = this._isLoading$.pipe(
  	switchMap( isLoading => {
      if(!isLoading) {
        return of(false)
      }else{
        return of(true).pipe(delay(1000));
      }
    })
  )

  start(){
    this._isLoading.next(true);
  }
  finish(){
    this._isLoading.next(false);
  }
}
https://fakestoreapi.com/
// component
export class HeroComponent {
 constructor(private activatedRoute: ActivatedRoute) {}
 ngOnInit() {
   this.activatedRoute.data.subscribe(({ hero }) => {
     // do something with your resolved data ...
   })
   // or
   this.hero = this.activatedRoute.data['hero']
 }

}

// resolve
@Injectable({ providedIn: 'root' })
export class HeroResolver implements Resolve<Hero> {
  constructor(private service: HeroService) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<Hero>|Promise<Hero>|Hero {
    return this.service.getHero(route.paramMap.get('id')).pipe(
      catchError(error => of('No data'))
    );
  }
}

// rota
@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'detail/:id',
        component: HeroDetailComponent,
        resolve: {
          hero: HeroResolver
        }
      }
    ])
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {}
import { combineLatest, Subject, map } from 'rxjs';

var price = 31.99;

/** Declare an Observable
 * Data we can observe
 * over time
 */
const qty$ = new Subject<number>();

/** Emit when the action occurs
 * Hey Observable,
 * here is a new value
 */
const onQuantityChanged = (quantity) => qty$.next(quantity);

/** React to emissions
 * Whenever you
 * change, I`II change
 */
const exPreice$ = qty$.pipe(map((q) => q * price));
const tax$ = exPreice$.pipe(map((t) => Math.round(t * 10.75) / 100));
const deliveryFree$ = exPreice$.pipe(map((q) => (q < 35 ? 5.99 : 0)));
const totalPrice$ = combineLatest([exPreice$, deliveryFree$, tax$]).pipe(
  map(([p, d, t]) => p + d + t)
);
totalPrice$.subscribe(console.log);
onQuantityChanged(2); // 70.86
// component
@ViewChild('inputName', {static: false})
obj: ElementRef;

ngOnInit(){
  this.skipLink()
}

skipLink() {
 this.obj.nativeElement.focus()
}
// html
postWithCategory$ | async

// component
postWithCategory$ = this.postService.postWithCategory$

// post.service.ts
postWithCategory$ = combineLatest([
  this.allPosts$,
  this.categoryService.allCategories$
]).pipe(
  map( ([posts, cat]) => this.mapCategories(posts, cat) )
)

allPosts$ = this.http.get<Post[]>(this.postsUrl).pipe(
  catchError(this.handleError)
);

mapCategories(posts: Post[], cat: PostCatergory[]): Post[]{
  return posts.map( post => ({
    ...post,
    category: cat.find( c => post.categoryId === c.id)?.name
  }) as Post )
}

// category.service
allCategories$ = this.http.get<PostCategory[]>(this.catUrl).pipe(
  catchError(this.handleError),
  shareReplay(1)
);
// html
<div *ngFor"let post of postsForUser$ | async">
 {{ post.title }}
</div>

// component
postsForUser$ = this.entedUser$.pipe(
 switchMap(userName => this.userService.getUserId(userName)),
 switchMap(userId => this.userService.getPostsForUserId(userId))
)

// service
private _userSubject = new Subject<string>();
enteredUser$ = this._userSubject.asObservable();

userChanged(userName: string): void{
  this.enteredUser.next(userName);
}

getUserId(userName: string): Observable<number>{
  return this.http.get<User[]>(`${userUrl}?userName=^${userName}$`).pipe(
   catchError(this.handleError),
   map(users => (users.lenght === 0) ? 0 : users[0].id)
  )
}

getPostsForUserId(userId: number): Observable<Post[]>{
  return this.http.get<Post[]>(`${postsUresgatrl}?userId=^${userId}$`).pipe(
   catchError(this.handleError)
  )
}
user$ = this.http.get<User[]>(url).pipe(
tap(data => console.log(JSON.stringfy(data))),
catchError(this.handleError)
)

privat handleError(err: HttpErrorResponse): Observable<never>{
  let errorMsg = `An error occurred: ${err.error.message}`;
  console.log(err);
  return throwError(()=> errorMsg)
}
//usage
import{MaybeObservable} from '/help/maybe-observable'
import{asObservable} from '/help/as-observable'
getGame$(catId: MaybeObservable<string>){
  return asObservable(catId).pipe(
    switchMap(id => of(this.getGame(id)))
  );
}

// help/as-observable.ts
import{isObservable,of} from 'rxjs'
import{MaybeObservable} from './maybe-observable'
export function asObservable<T>(value: MaybeObservable<T>){
  return isObservable(value) ? value : of(value);
}

// help/maybe-observable.ts
import{Observable} from 'rxjs';
export type MaybeObservable<T> = T | Observable<T>;
catchError( (err, source) => source)
catchError(this.handleError)


  private handleError(err) {
    // in a real world app, we may send the server to some remote logging infrastructure
    // instead of just logging it to the console
    let errorMessage: string;
    if (err.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      errorMessage = `An error occurred: ${err.error.message}`;
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      errorMessage = `Backend returned code ${err.status}: ${err.body.error}`;
    }
    console.error(err);
    return throwError(errorMessage);
  }
//html
<div *ngIf="let notice of (news$ | async)"> ...

//compoent
refreshTImer$ = timer(0, 30000)
news$ = this.service.news$
/*ngOnInit*/
this.sub = this.refreshTimer$.subscribe(this.service.refresh$)
/*ngOnDestroy*/
this.sub.unsubscribe()

//service
loadNews$ = this.http.get('/newsfeed')...
refresh$ = new BeharviorSubject(null);
news$ = this.refresh$.pipe(
 exhaustMap( () => this.loadNews$)
)
// app.component.html
<div *ngIf="productSuppliers$ | async as suppliers">
 	<div *ngFor="let supplier of suppliers">
		{{ supplier.name }}
	</div>
</div>
 
 
// app.component.ts
productSuppliers$ = this.productService.productSuppliers$;
 
 
// product.service.ts
selectedProduct$ = ...
productSuppliers$ = this.selectedProduct$.pipe(
  switchMap(product =>
	forkJoin(
		product.supplierIds.map(
			supplierId => this.http.get<Supplier>(`${url}/${supplierId}`))
   )
);
// app.component.html
<div *ngIf="productSupplier$ | async as supplier">
  	{{ supplier.name }}
  </button>
</div>
 
 
// app.component.ts
productSupplier$ = this.productService.productSupplier$;
 
 
// product.service.ts
selectedProduct$ = ...
productSupplier$ = this.selectedProduct$.pipe(
  switchMap(product => this.http.get<Supplier>(`${url}/${product.supplierId}`))
);
// app.component.html
<div *ngIf="selectedProduct$ | async as product">
  	{{ product.name }}
  </button>
</div>


// app.component.ts
selectedProduct$ = this.productService.selectedProduct$;


// product.service.ts
products$ = this.categorySelectedAction$.pipe(
  switchMap( catId => this.http.get<Product[]>(this.url+'?cat='+catId))
  .pipe(...);
        
private productSelectedSubject = new Subject<number>();
productSelectedAction$ = this.productSelectedSubject.asObservable();

selectedProduct$ = combineLatest([
  this.products$,
  this.productSelectedAction
]).pipe(
  map(([products, selectedProductId]) => 
   products.find(product => product.id === selectedProductId)
  ));

// app.component.html
<div *ngIf="products$ | async as products">
  <button *ngFor='let product of products'>
  	{{ product.name }}
  </button>
</div>


// app.component.ts
products$ = this.productService.products$;


// product.service.ts
private categorySubject = new Subject<number>();
categorySelectedAction$ = this.categorySubject.asObservable();

products$ = this.categorySelectedAction$.pipe(
  switchMap( catId => this.http.get<Product[]>(this.url+'?cat='+catId))
  .pipe(
  	tap(console.log),
  	catchError(this.handleError)
   )
);

selectedCategoryChanged(categoryId: number): void{
  this.categorySUbject.next(categoryId);
}
import { Directive, ElementRef, HostBinding, HostListener } from "@angular/core";
 
@Directive({
    selector: '[appDropdown]'
})
 
export class DropdownDirective {
@HostBinding('class.open') isActive = false;
 
@HostListener('document:click', ['$event']) onClick(event: Event) {
        this.isActive = this.elRef.nativeElement.contains(event.target) ? !this.isActive : false;
    }
 
    constructor(private elRef: ElementRef) {}
}
// app.component.html
<div *ngIf="products$ | async as products">
  <button *ngFor='let product of products'>
  	{{ product.name }}
  </button>
</div>

// app.component.ts
products$ = this.productService.products$;

// app.service.ts
products$ = this.http.get<Product[]>(this.url)
  .pipe(
  	tap(console.log),
  	catchError(this.handleError)
   );
    {
        "/api/*": {
            "target": "https://localhost:44358/",
            "secure": false
          }
    }

 "start": "ng serve --proxy-config proxy.config.json",
#imports 
import { Observable, of } from 'rxjs';
import { tap, delay } from 'rxjs/operators';

#service
isUserLoggedIn: boolean = false;

  login(userName: string, password: string) {
     console.log(userName);
     console.log(password);
     this.isUserLoggedIn = userName == 'admin' && password == 'admin';
     localStorage.setItem('isUserLoggedIn', this.isUserLoggedIn ? "true" : "false"); 

  return of(this.isUserLoggedIn).pipe(
     delay(1000),
     tap(val => { 
        console.log("Is User Authentication is successful: " + val); 
     })
  );
  }

  logout(): void {
  this.isUserLoggedIn = false;
     localStorage.removeItem('isUserLoggedIn'); 
  }
To make HttpClient available everywhere in the app,

open the root AppModule,

import the HttpClientModule from @angular/common/http,

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

add it to the @NgModule.imports array.

imports:[HttpClientModule,  ]
  getPerson(id: number) {
    return this.http.get<Person>(`${this.baseUrl}api/profile/person/${id}`);

  }
    this.http.getAbout(person.id).subscribe((data: About[]) => { this.about = data[0]; this.loader = false }, error => {
      retry(3),
        this.errorMessage = error;
    });
typescript adds types to JavaScript.
/////////////////////////////////////////// function arguments
Function arguments & return types:
let greeting : (name: string) => string;
greeting = function (name: string) {
    return `Hi ${name}`;
};
/////////////////////////////////////////// object Type
let employee: object;
object type represents any value that is not a primitive type,while Object type describes functionalities that available on all objects;toString,valueof...

//////////////////////////////////// array & tuple
array can store mixed type values
let arr: type[]
A tupple is an array with a fixed number of elements whose types are known.

//////////////////////////////////// any type
Use the any type to store a value that you don’t actually know its type at the compile-time

//////////////////////////////////// void type
 you use the void type as the return type of functions that do not return a value. 
 
//////////////////////////////////// union types
  combine multiple types into one type
  let result: number | string;
/////////////////////////////////////////// type aliases
define a new name for an existing type,useful for union types.
type newName=existing type;
type alphanumeric = string | number;
/////////////////////////////////////////////// String Literal Types
define a type that accepts only a specified string literal;
let mouseEvent: 'click' | 'dblclick' | 'mouseup' | 'mousedown';

/////////////////////////////////////  Type inference
TypeScript guesses the type,when you initialize the variable.

/////////////////////////////////////  optional parameters
Use the parameter?: type syntax to make a parameter optional.
Use the expression typeof(parameter) !== 'undefined' to check if the parameter has been initialized.


/////////////////////////////////////  default parameters
function name(parameter1=defaultValue1,...) {
   // do something
}
To use the default initialized value of a parameter, you omit the argument when calling the function or pass the undefined into the function.

/////////////////////////////////////  classes
ES5 allows classes and Ts adds type annotations

/////////////////////////////////////  inheritance
you use the extends keyword.
To call the constructor of the parent class in the constructor of the child class, you use the super() syntax. 
Method overriding:just redefine the method

/////////////////////////////Static Methods and Properties
a static property is shared among all instances of a class.

///////////////////////////// abstract classe
define common behaviors for derived classes to extend,
  

///////////////////////////// type guards
 used to identify or narrow down the type of a variable using instanceOf and typeOf.
 User can define type-guards:
 function isCustomer(partner: any): partner is Customer {
    return partner instanceof Customer;
}
///////////////////// casting types
to convert a variable from one type to another.using as pr <>;
# method 1
import * as wasm from 'wasm/pkg'

ngOnInit()
  wasm.greet()


#method 2
import { greet } from 'wasm/pkg/wasm_bg.wasm'; #|| from 'wasm/pkg'
  ngOnInit()
    greet()

# method 3
ngOnInit() {
  const rust = import('../../wasm/pkg');
  rust.then(m => m.greet()).catch(console.error);

  rust.then(m => console.log(m.add(2, 2), 'added'));
}

# Terminal command to build lib.rs 
wasm-pack build
npx cap open ios #abrir o projecto no xcode

npx cap open android #abrir o projecto no android
<dict>
+  <key>NSCameraUsageDescription</key>
+  <string>To be able to scan barcodes</string>
</dict>
<?xml version="1.0" encoding="utf-8"?>
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:tools="http://schemas.android.com/tools" <-- adicionas esta linha não removendo nada e seguindo esta lógica

  package="com.example">

  <application
+    android:hardwareAccelerated="true" <-- adicionas esta linha não removendo nada e seguindo esta lógica
  >
  </application>

+  <uses-permission android:name="android.permission.CAMERA" /><-- adicionas esta linha não removendo nada e seguindo esta lógica

+  <uses-sdk tools:overrideLibrary="com.google.zxing.client.android" /><-- adicionas esta linha não removendo nada e seguindo esta lógica
</manifest>
ionic build --prod

#caso quiseres colocar a app para android dás o seguinte comando:
npm install @capacitor/android
npx cap add android

#caso quiseres colocar a app para iOS dás o seguinte comando:
npm install @capacitor/ios
npx cap add ios


#no final dão estes dois ultimos comandos

npx cap sync
npx cap copy Android ou ios #dependendo do qual escolheram
...

<ion-content class="scanner-hide" *ngIf="scanStatus == false">
  <div class="padding-container center">
    <ion-button color="primary" (click)="scanCode()"><ion-icon slot="start" name="qr-code-outline"></ion-icon> Scanear Código</ion-button> <!-- Botão que chama a função do scanner-->
  </div>
  <ion-card>
    <ion-card-content><h1>{{ result }}</h1></ion-card-content> <!-- mostra o resultado do scan -->
  </ion-card>
  
  <div class="scanner-ui"> <!-- Quando estamos a scanear, chama esta classe-->
    ...Scanner Interface
    </div>
    <div class="ad-spot"></div>
</ion-content>
...
import { BarcodeScanner } from '@capacitor-community/barcode-scanner';



...



export class HomePage {
  public scanStatus:boolean = false; // no inicio da página, coloca o estado do código qr para falso
  public result:any;

  constructor() {}


  async scanCode () {

    this.setPermissions(); /* chama as permissões à camera */
  
    BarcodeScanner.hideBackground(); // coloca o fundo transparente
    this.scanStatus = true; // ao mudar esta variável para true, estamos a puxar o qr code scanner 
    document.body.classList.add("qrscanner"); // adiciona a classe css que fizemos no global
    const result = await BarcodeScanner.startScan(); // começa a fazer scan e espera por um result
  
  // se o qr scanner detectou algum número, então ele faz o código abaixo
    if (result.hasContent) {

        
        this.scanStatus = false; //como é obvio, ele tem de desligar o scanner ao obter o resultado
        BarcodeScanner.stopScan(); //para o scan
        this.result = result.content; // passa o resultado para a variável global result
        BarcodeScanner.showBackground(); //volta a mostrar o fundo
        document.body.classList.remove("qrscanner"); //remove a classe css que criamos no global
    
    }
  }

  async setPermissions(){
    const status = await BarcodeScanner.checkPermission({ force: true }); /* força a permissão para true, caso o utilizador não aceite, o scanner não funciona */
    if (status.granted) {
      // the user granted permission
      return true; // se o utilizador aceitou as permissões retorna true
    }
  
      return false; // se o utilizador não aceitou retorna false
  }
}
.scanner-ui { display: none; }
.scanner-hide { visibility: visible; }

body.qrscanner { background-color: transparent; }
body.qrscanner .scanner-ui { display: block; }
body.qrscanner .scanner-hide { visibility: hidden; }
ionic start qrcode blank --type=ionic-angular
<router-outlet (activate)="onActivate($event)"></router-outlet>

onActivate(event) {
   // window.scroll(0,0);

   window.scroll({ 
           top: 0, 
           left: 0, 
           behavior: 'smooth' 
    });

    //or document.body.scrollTop = 0;
    //or document.querySelector('body').scrollTo(0,0)
    ...
}
import { HttpClient, ..., HttpBackend } from '@angular/common/http';

@Injectable()
export class TestService {

  private httpClient: HttpClient;

  constructor( handler: HttpBackend) { 
     this.httpClient = new HttpClient(handler);
  }
....
module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            ident: "postcss",
            syntax: "postcss-scss",
            plugins: [
              require("postcss-import"),
              require("tailwindcss"),
              require("autoprefixer"),
            ],
          },
        },
      },
    ],
  },
};
//html

<nick-select class="beta-mr-28" [nickCrudField]="formulario.select" [options]="selectOptions">
</nick-select>

<span>opção selecionada: {{form.tournamentType.complexValue.value}}</span>

//JSON

"form:formulario": { //inicializa um form.
  "select": { //id do campo.
    "id": "select",
    "title": "Select", //Título, será exibido como label acima do select gerado.
    "metadata": { //Paremetros opcionais.	
      "defaultValue": 0 //index padrão do array options.
    }
  }
},
  //inicializa array
"selectOptions": [ 
  //objeto contendo as opções a serem exibidas no nosso select.
  {
    "key": 0,
    "value": "opção 1"
  },
  {
    "key": 1,
    "value": "opção 2"
  }
]

//saida: opção selecionada: opção 1
//html

<form>
  <nick-input style="width: auto;" class="beta-mr-28" [nickCrudField]="formulario.nome" placeholder="Informe seu nome">
  </nick-input>
</form>

<span>seu nome é: {{nome.value}}</span>

//JSON

//Formulário padrão

"form:formulario": { //inicializa um form.
  "nome": { //id do campo.
    "id": "nome",
    "title": "Nome", //Título, será exibido como label acima do input gerado.
    "metadata": { //Parametros opcionais.
    "required": true //Validator de campo requerido
    }
  }
}
//html

<span>Valor da variável: {{originNomeVar}}</span>

//JSON

{
    "onLoad": [
        {
            "index": 0,
            "actions": [
              	{
                    "set:nomeVar": {
                        "value": "1234"
                    }
                },
                {
                    "set:originNomeVar": {
                        "originField": "nomeVar"
                    }
                }
            ]
        }
    ]
}

//Saída Valor da variável: 1234
//html
<span>Valor da variável: {{nomeVar}}</span>

//JSON

{
    "onLoad": [
        {
            "index": 0,
            "actions": [
                {
                    "set:nomeVar": {
                        "value": "123"
                    }
                }
            ]
        }
    ]
}

//Saída: Valor da variável: 123
const { scrollTop, offsetHeight } = document.documentElement;
const { innerHeight } = window;
const bottomOfWindow = Math.round(scrollTop) + innerHeight === offsetHeight;

if (bottomOfWindow) {
  console.log('Bottom of window');
}
  ngAfterViewInit(): void {
    const vendor = this.activatedRoute.snapshot.params.vendor_id;

    combineLatest([
      this.filterChanged$.asObservable().pipe(
        startWith({}),
        tap(() => this.pagination.reset())
      ),
      this.sort.sortChange.pipe(
        startWith({}),
        tap(() => this.pagination.reset())
      ),
      this.pagination.pageChanged.pipe(startWith({})),
    ])
      .pipe(
        tap(() => (this.isLoading = true)),
        map(([filterData]) => {
          let orderFilter: OrderFilterInput = {
            vendor,
          };

          if ('dateFrom' in filterData && 'dateTo' in filterData && 'city' in filterData) {
            const { dateFrom, dateTo, city } = filterData;

            orderFilter = {
              ...orderFilter,
              ...(
                dateFrom && dateTo && {
                  createdRange: {
                    gte: dateFrom,
                    lte: dateTo,
                  }
                }
              ),
              city
            };
          }

          return orderFilter;
        }),
        switchMap((orderFilter) =>
          merge(
            this.updateOrders$
              .asObservable()
              .pipe(map(() => ({ callCount: 1, orderFilter }))),
            timer(0, 30 * 1000).pipe(
              map((callCount) => ({ callCount, orderFilter }))
            )
          )
        ),
        switchMap(({ callCount, orderFilter }) => {
          this.newOrderCheckerService.makeFetch();

          const fetchOrders$ = this.orderService.findAll(
            this.getSortData(),
            callCount === 0
              ? this.pagination.getPaginationData()
              : this.pagination.getCachedPaginationData(),
            orderFilter
          );

          return PaginationComponent.paginationSetter$(this.pagination)(
            () => fetchOrders$
          );
        }),
        tap(({ orders }) => {
          this.orders = orders;
          this.data = this.getGroupedOrders(orders);
          this.isLoading = false;
        }),
        filter(() => this.isAdmin()),
        tap(({ orders }) => {
          if (
            !orders.some((order) => order.cancellationReason?.blinkForAdmin)
          ) {
            return;
          }

          this.audioService.play(AvailableAudio.NOTIFICATION);
        }),
        untilDestroyed(this)
      )
      .subscribe();
  }
   /*
    --------------------------
   */
    ** Pending **
  -Methods:
call(), apply(), bind()



  **

  Book :> The Principle of Object oriented Javscript

    **
   : Dereferencing Objects //Is used to Clear the memory on browser           engine.
var object1 = new Object();
// do something
object1 = null;
    // dereference  
   **
    
    **
    : Deleting a value from Object.
    > delete objName.key;
    **
      
    **
    : Function Example -
  function reflect(value) {
    return value;
  }
// is the same as
var reflect = new Function("value", "return value;"); 
     **
        
      **
  arrName['push']('3'); //This is also valid ( using bracket              notation )
       **

      ** // It will store the values as an Object ( String ).
  let nameVariable = new String();
nameVariable.fname = 'Karan';
nameVariable.lname = 'Singh';
       **
           
       ** hasOwnProperty **
    let obj = { fname: "Karan", lname: "Singh" }

    > console.log('fname' in obj)  //true
    > console.log('lname' in obj) //true

    > console.log('toString' in obj)  //true 
    // ( Inbuilt methods will also return true )

    > console.log(obj.hasOwnProperty('toString')) //False
    **
           
       **
           //Ways to access Properties in Object
         > Object.keys(objName); //Will return keys
         > Object.values(objName); //Will return values 
  
       **
       //To check if Properties are Enumerable                                                (propertyIsEnumerable).
    > (objName.propertyIsEnumerable(key)); //true or false

      Object.defineProperty(obj, prop, descriptor) //Syntax
       **
        //We can change the default state of the Object.

        var person1 = {};
       **
      Object.defineProperty(person1, "name", {
        value: "Nicholas",
        enumerable: true,
        configurable: true,
        writable: true
      }); //It will create 'name' in person1 Object with 'descriptor'.

      Object.defineProperty(person1, "name", {
      enumerable: false
      }); //We can define in Single Lines as well ( Depending upon our need )

      Object.defineProperty(person1, 'property1', {
        value: 42,
        writable: false
      });// 'property1' can not be overwritten.


      **
     //Preventing Object Modification      
       //Syntax
      > Object.preventExtensions(person1); //false
            /*It will not allow to add new properties to object 'person1'.
            */
      //isExtensible() (How to check?)
      > console.log(Object.isExtensible(obj)); //It will tell whether it's               extensible or not ( true / false )

**
       //Freezing the Object. ( Cant not add/remove. ( read-only ) )
        > Object.feeze(objName);

        //isFrozen() ( How to Check? )
       > console.log(Object.isFrozen(objName)); //Will return true or false.


   ** //Three methods which does not allow mathods to add/remove properties.
        > Object.preventExtensions(objName)
        > Object.seal(objName)
        > Object.freeze(objName)
        //To how to check, Use these methods.   
        console.log(Object.isExtensible(person1));
        console.log(Object.isSealed(person1));
        console.log(Object.isFrozen(person1));



     **//Using Prototypes with Constructors

          function Person(name){
            this.name = name;
          }

          Person.prototype.sayName = function(){
            return this.name;
          }

          let karan = new Person("Jaskaran");













/*
 ---------------------------------------------------------------------
*/
--------------------
                                //Number


Number.isNaN(24);
// False.

let number1 = -Infinity;
let number2 = Infinity;  
--------------------
                                   //String


String(77).padStart(6,0);
// 000077


let str = 'Jaskaran Singh Pannu';
str.repeat(10)

console.log("Karan- ".repeat(4));
//Karan- Karan- Karan- Karan-
-------------------
-------------------

-------------------
                                   //Object
  
  
let {name , age} = {name: "Faraji", age: 23};
console.log(name , age);
// → Faraji , 23


let obj = { name  : 'karan' };
consol.log( 'name' in obj);
//true;

     // Prototype ( Just to check if the certain properties are there.
Object.prototype.addNewMethod = function(){ return "Yeah"};
console.log('addNewMethod' in Object);
//true;
console.log('toString' in Object);
//true;

 //hasOwnProperty  ( It will just show the 'obj's properties ( code written ) , Not of it's parent ( Object).
let obj = { name : 'karan' };
obj.hasOwnProperty("name");
//true;
obj.hasOwnProperty('toString');
//False;

 //Get  // Set //Statics.
let obj = {
  //keyword 'get'
  get powerOne(){ return "Power 1" },
  powerTwo : function(){
    return "Power2, Old School."
  }
};
obj.powerOne;
// OR. (The Only difference is, If we are using keyword "get", We don't have to use "()" while calling any function.
obj.powerTwo();
------------------------
                                //Classes
class basics{
  constructor( name  ){
     this.name = name;
  }
  skillOne(skill){
    return this.name + " is " + skill
  }
}

class ChildOne extends basics{
  constructor( name , age , country ){
    super( name )
    this.age = age;
    this.country = country;
  }
  skillTwo(){
    return " Skill Two here... "
  }
}
----------------------
//instanceof
let arr = {};
console.log(arr instanceof Object)
// true.
let arr2 = []
console.log(arr2 instaceof Object);
// true ( Object is main base for all the non-primitives data types ( functions / arrays ).
------------------------
//Object.freeze
let object = Object.freeze({value: 5});
object.value = 10;
console.log(object.value);
// → 5
-----------------------
                               //HOF
  //Data.
const companies = [
  {name: "Company One", category: "Finance", start: 1981, end: 2005},
  {name: "Company Two", category: "Retail", start: 1992, end: 2008},
  {name: "Company Three", category: "Auto", start: 1999, end: 2007},
  {name: "Company Four", category: "Retail", start: 1989, end: 2010},
  {name: "Company Five", category: "Technology", start: 2009, end: 2014},
  {name: "Company Six", category: "Finance", start: 1987, end: 2010},
  {name: "Company Seven", category: "Auto", start: 1986, end: 1996},
  {name: "Company Eight", category: "Technology", start: 2011, end: 2016},
  {name: "Company Nine", category: "Retail", start: 1981, end: 1989}
];
const ages = [  10, 0,10, 40, 50 , 88, 9 , 20 ,89, 100 ,6];


//Sort
let sort = ages.sort((a , b ) => a - b );
sort = companies.sort( (a , b ) =>  a.start -b.start    )

//Reduce , Suming the Arrays.
let totatAges = ages.reduce(( total, item )=> total + item, 0 );
let totalYears = companies.reduce(( total , item ) => total + (item.end - item.start)
,0)

let out = nums.reduce(( firstItem , singleItem ) => {
 let max = firstItem > singleItem ? firstItem : singleItem;
 return max; 
})


// There is another method called => "Find" 

                        /* "Every" */ ( it return boolean value ) 
//It will test whether all elements in the array pass the provided function.
let output = students.every((item)=>{
  return item.grade >= 100;
})

                       /* "SOME"  */  ( it return boolean value )
//Similar to every, but returns true if ANY of the array elements pass the test function
let output = students.some((item)=>{
  return item.grade >= 100;
})



//Combined
let combined = ages
                   .sort((a,b) => a-b)
                   .filter( item => item <= 10 )
                   .map( item => item * 1 ) 
                   .reduce( (total,item)=> total + item ,0 );

//Destructing 
//Objects example
let  {name, age, ...evrythingElse} = {  name : 'Jaskaran',  age : 34, country : "U.S", cool : true }
console.log(name); //Jaskaran
console.log(age); //34
console.log(evrythingElse); // { country:'U.S', cool: true }

//Array Example
let arr = ["Jaskaran","Singh","Pannu"];
let  [firstName, ...everythingElse ]  = arr;
console.log(everythingElse); // ['Singh', 'Pannu']


//Param Destructing
let fullName = ({fN, lN }) =>{ return fN + " " + lN }

let objName = {
  fN : "Karan",
  lN :"Singh"
}

fullName(objName);



/* Async */


//1 way.
fetch("https://icanhazdadjoke.com/slack").then((res)=>{
        res.json().then((data)=>{
        console.log(data)
    })
});

//2nd Way
let link = "https://icanhazdadjoke.com/slack";
let xhr = new XMLHttpRequest();

xhr.open('GET',link, true);
xhr.send();

xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
    console.log(xhr.responseText);
 }
}


// By Maxi.

//Installing Bootstrap ( locally )
 > npm install bootstrap@3 --save


// Data Binding.
..> Output Data
/* 
1.String Interpolation :
Should be a string, Or can be converted to string.
*/
 <h3>My Name is {{ name }}  {{'Singh'}}   {{ lastName() }} </h3> 

/*
2. Property Binding :
*/
  ( [propert] ='data' )

.HTML
<button class="btn btn-primary" [disabled]="!allowNewServer">Click here</button> <b [innerText] = "allowNewServer">  </b>

.TS
  setTimeout(()=>{ this.allowNewServer = true;
  },2000)
// 'disabled' is the property here, We are toggling the boolean value to disable or enabled the between ( if it's true then it will be disabled else btn will be enabled. )


..< React to Events
 ( (event) = 'expression' )

/*
3. Two way Binding : 
*/
  ( [(ng Model)] = 'data' )
/* 
> Commands for npmp pack or Terminal.
*/

// Install Cmd ( Globally ).
npm install-g typescript  

//Adding Bootstrap.
npm install bootstrap --save



-----------------------------------------------------------


//Typescript
//Data types
string
number
boolean
string
string[]   //Array of Strings
number[]   //Array of Numbers
any[]      //Array of any Data type
undefined  //undefined
void       //undefined   or if the value won't be returned ( void ( khaali ) )
enum
any

let canBeOneOfTheseTwoType : string | boolean;  // The value can be "string" or "boolean".
let data : number | boolean | string = '980033' ; // Valyue can be 1/3 data types.
let data2 : any = "Jaskaran"; //Any type of data type can used. 

let mixArray:[string, number, string, boolean] = ["Jaskaran", 1996, "Singh", true]; //Structure has to be same.

enum Color {Red, Green, Blue};
let data: Color = Color.Red;   //Will return 0 
let data2: Color = Color.Blue; // Will return 2

//Default Parameter.
function check(a:string, b:string = '99'):string{
    return "Default Parameter"
}

//Optional Parameter.
function check(a:string, b? :string ):string{
    return " b is optional here "
}

//Having multiple data types and optional argument.
function check(n1: number | boolean , n2? :number | string) { 
  return "Optional Paramter and multiple Data types"
}

//Interface
interface IAPIResponse {
    name : string,
    age : number
}

function playerOne(): IAPIResponse {
    return {
        name : 'Jaskaran',
        age : 20
    }
}

function playerTwo(): IAPIResponse {
    return {
        name : "Karan",
        age : 26
    }
}

console.log(playerOne());
console.log( playerTwo());




             /*  --------------- Class 1 ------------------ */




//CMD commands for TSC.
-h, -help
-w, -watch
--pretty
--all
-v, --version
--init    // Initialize
-p, --project
-b, --build
-t, --target
-m, --module

//To Change from TS to JS.
tsc index.ts //It will output the new file in the same directory with "index.js"


       /*   --------------------  Class 2  ------------------------- */

// Module and Component
 
 module1
    ->component1-1
    ->component1-2
    ->component1-3
    ->component1-4

 module2
    ->component2-1
    ->component2-2
    ->component2-3
    ->component2-4

 module3
    ->component3-1
    ->component3-2
    ->component3-3
    ->component3-4
  // Components are small parts of module. And App is divided into multiple modules(  Parent )

Component:
    M : Data ( will control V & C )
    V : template ( .html )
    C : logic  ( .ts )


//Meta Data
@NgModule {   //@NgModular is called decorator
  //I s Module
}
export class{}

@Component {    //@Component is called decorator
  //Is a Component 
}
export class{}

@Injectable {   //@Injectable is called decorator
  //Is a Service
}
export class{}


//On Start
   1. main.ts --> App Module
   2. App Module --> 
     
     
 // Inserting as component    //Default set up.
<div app-products></div>  
@Component({
  selector: '[app-products]'
 }
           
//Inserting as a Class
<div class="app-products"></div>           
@Component({
  selector: '.app-products'
}



    /*   --------------------  Class 3  ------------------------- */ "{}" is a Class.

//Event Binding:
// .html
<button (click) ="willDoSomething();"></button>   //DOM to component.
//.ts

--------------------------------------
/*
 1. Property Binding:
//#CASE ( Passing the values/data from parent Component "App" to child component"Header" )
( PARENT ), 
*/
>app.module.ts
import { FormsModule } from '@angular/forms';
imports: [
  FormsModule
]

  {
     list = [
    { Name: "nike", Product: "Shoes" },
    { Name: "Apple", Product: "Phones" },
    { Name: "BB", Product: "Software" },
    { Name: "Samsung", Product: "Chips" },
  ]
 }

----------------------------

 >app.html
  <app-header [productsOne]="list"></app-header>
-------------------------
>header.html
    <tr *ngFor='let item of productsOne'>
      <td> {{item.Name}} </td>
      <td>  {{ item.Product }} </td>
    </tr>
-------------------------
 >header.ts
import {  Input } from '@angular/core';
{
  @Input()
  productsOne: any;
}

                            --------------------------

//#CASE ( Passing the values/data from Child Component "Header" to Parent component"App" )
/*
Event Binding:
*/
>header.html
<button class="btn" (click)="childButtonClicked();">ChildButton</button>
--------------------------------                                    
>header.ts
import {  Output, EventEmitter } from '@angular/core';
 {
     constructor() { 
     this.dataOne = new EventEmitter();
     }
   
     @Output()
     dataOne: EventEmitter<any>;

     childButtonClicked(){
         this.dataOne.emit({
           name : "Karan",
           age : "25"
         }); 
 }
--------------------------------

>app.html
<app-header (dataOne)="dataComingFromChild($event);" ></app-header>
   
---------------------------------
>app.ts                                    
  dataComingFromChild(data:any){
    console.log(data);
  }
-----------------------------------
  
To flow data one direction.
[ngModel] ='val' ; 

 To flow data both the direction.
[(ngModel)] ='val' ;  ( value will be binded )

   
     /* Directives
      1. Components as directives (simple/single component)
      2. Structural Directives
        ngIf
        [hidden]
        ngFor
        ngSwitch
      3. Attribute Directives
       [ngStyle]
       [ngClass]
      4. Custom Directives
      
     
     */
   
// Structural Directives:   
   
   /*
    ngIf
    [hidden]
    ngFor
    ngSwitch
   */
   
"*ngFor" is known as structure directive, As it changes the structure of the web page.   

//ngIF - Structural directive
<div *ngIf='condition'>
  Content will Render if condition is true
</div>
   
//ngClass   
 /*
 Add or Remove CSS classes ( using Logic )
 */

 /*   --------------------  Class 4  ------------------ */
//*ngIf
>> #Case   
header.html
<div>
  <div *ngIf="defaultBool">
    Data is in the First Slot
  </div> 
  <div *ngIf="!defaultBool">
    Data is in the Second Slot
  </div> 
 
  <button class="btn btn-block" (click)='toggleData()'>
    Click to Toggle
  </button>
 </div>
   
header.ts   
  defaultBool:boolean = true;
  toggleData(){
    this.defaultBool = !this.defaultBool;
  }
      ----------------------------------------------------
//Else-if   
 #case  
>header.html   
  <div *ngIf="defaultBool else toggleIDName">
    Data is in the First Slot
  </div> 

 <ng-template #toggleIDName>
  <div>
    Data is in the Second Slot
  </div> 
 </ng-template>
 
  <button class="btn btn-block" (click)='toggleData()'>
    Click to Toggle
  </button>   
   
> header.ts   
  defaultBool:boolean = true;
  toggleData(){
    this.defaultBool = !this.defaultBool;
  }
       ----------------------------------------------------
//[hidden] property: ( mostly used for Small parts )
   
.html
<div [hidden]='defaultHiddenValue'>
 Hidden Example </div>  	 
<button (click)="toggleHidden"> Click to hide </button>
   
.ts
   defaultHiddenValue:boolean = true;
   toggleHidden(){
     this.defaultHiddenValue = !this.defaultHiddenValue;
   } 
  
** The Hidden property will hide the stuff from the web page( Will be visible in Source Code ), Where as 'NgiF' will completely remove/add the Elements/element from DOM,   
      ----------------------------------------------------
// Ngswitch
  #syntax:
 <div [ngSwitch]='companiesList'>
      <p *ngSwitchCae="aws">AWS stuff </p>
      <p *ngSwitchCae="google">google stuff </p>
      <p *ngSwitchCae="MS">MS stuff </p>
      <p *ngSwitchCae="Applce">Applce stuff </p>
      <p *ngSwitchDefault="Defaul Value"> kites </p>
  </div>
   
 
.html
  <div [ngSwitch]='selectCourse'>
    <div *ngSwitchCase="'react'">react</div>
    <div *ngSwitchCase="'angular'">angular</div>
    <div *ngSwitchCase="'vue'">vue</div>
    <div *ngSwitchDefault> Default value..... </div>
  </div>   
<button (click)="reactCourse()">React Developer </button>
<button (click)="angularCourse()">Angular Dev </button>
<button (click)="vueCourse()">Vue Developer </button>  
   
.ts
   {
    selectCourse:string = '';

    reactCourse(){ this.selectCourse = "React"; }
    angularCourse(){ this.selectCourse = "Angular"; }
    vueCourse(){ this.selectCourse = "Vue"; }     
     }
   
      ----------------------------------------------------
      
 //Attribute Directives
      /*
      [ngStyle]
      [ngClass]
      */
      
      
// ngStyle: 
.html
<h1 [ngStyle]= "{ 'color' : selectedColorName }">
 "Some Text here";
</h1>
<button (click)="redColor()"> click to red it </button>
.ts
selectedColorName:string = 'gray'; //By default the color will be gray. 

 redColor(){
   this.selectedColorName = 'red';
 }  
 //We can change the color value dynamically as per our need.
   
   ----------------------------------------------------
// ngClass : attribute Directive.    
.html
  <h2 [ngClass] = "{ 'className1' : variableName == 'average', 'className2' : variableName == 'good' }" >
   {{ selectCourse }} :  {{variableName}}   // Will manipulate the classes depending upon 'variableName' value.
  </h2>

.ts
  variableName:string = "average"; //Default value.
//We can change the variableName value dynamically as per our need, To 'average' or 'good' or anything and then set that value in HTML attribute value. 
 
   ----------------------------------------------------
   /*
 //Custom directives   
    :When inbuilt directives are not sufficient, We create       our own directives as per our need. 
    
     #syntax: 
     @Directive()  //decorator
     class myDirectiveName {
       //class
     }
   */
   
   > ng g directive myCustomDirectiveName //CLI

customDirective.ts
import { ElementRef, HostListener } from '@angular/core';

  constructor( private eleRef: ElementRef ) { 
   }
   @HostListener('mouseenter') onEnter() {
     this.eleRef.nativeElement.style.background = 'gray';
     this.eleRef.nativeElement.style.cursor = 'pointer';
   }
   @HostListener('mouseleave') onLeave(){
    this.eleRef.nativeElement.style.background = 'initial';
   }

header.html
  <div>
    <ol>
      <li appMyCustomDirective>Nike</li>
      <li appMyCustomDirective>UA</li>
      <li appMyCustomDirective>Roots</li>
    </ol> 
  </div>
   
   

  /*
                     PIPES
   : PIPEs are used to improve/increase the functionaility of the     app/page.
   
   Types:
   1.Inbuilt Pipes
   2.Custom Pipes.
  */

1.Inbuilt Pipes
#example 
> header.ts

dob = new Date();
price = 10;
name = 'jaskaran'
 
 > header.html

  <ol>
 <li> {{ name | uppercase }} </li>
 <li> {{ name | lowercase }} </li>
 <li> {{ name | titlecase }} </li>
  </ol> 

  <div> 
    Short date formate: {{ dob | date: 'short' }}   <br>
    Full date formate: {{ dob | date: 'full' }}    <br>
    Custom Format1: {{ dob | date: 'MM/dd/YYYY' }} <br>
    Custom Format2: {{ dob | date: 'dd-MM-YYYY' }} <br>
  </div>

 <div>
   currencyDollar (default) :  {{ price | currency }}  <br>
   currency Pound :  {{ price | currency:'GBP' }}  <br>
   currency Rupee :  {{ price | currency :'INR' }}  <br>
 </div>

> 2.Custom Pipes.
 - cli
 ng g pipe customPipeName

#syntax: ( CLI will automatically generate the structure for us. )

 @Pipe()
 export class customPipeName{
 }

#Example 1.
.custom.pipe.ts
export class CustomPipePipe implements PipeTransform {
  transform(value: string ): string {
    return value + "-Extra String..........";
 //value is the "actual" item to work on.
  }
}

header.html
 {{ 'Jaskaran' | customPipe }}
   //Output will 'Jaskaran-Extra String..........' 

#Example 2.
> footer.ts
  list = [
    { Name: "nike", grade: "A" },
    { Name: "Apple", grade: "B" },
    { Name: "Samsung", grade: "A" },
  ]

> gradingPipe.ts
  transform(value:any, ...args: any[]): any {
    //Value will be the complete data ( "list" ).
     //args will be values provided'Arguments' ( right side of pipe name in HTML ),
    const grade = args[0];
    const filteredStudents = value.filter(( item:any )=>{
      return (item.grade == grade);
    })
    return filteredStudents;
  }

> footer.html
 <tbody>
   <tr *ngFor="let item of list  | filterGrades:'A' ">
         <td> {{ item.Name | uppercase }}  </td>
       <td>       {{ item.grade}}  </td>
   </tr>
 </tbody>


//Services
    :Is used to share the data and the logic between different components. 

     /*   --------------------  Class 5  ---------------- */
   
   
     
    
    
     /* --------------------  Class 6  ------------------ */



     
.config-heading {
  border-bottom: 1px solid #cccccc;
  text-align: center;
  padding-top: 0.5rem;
  margin-bottom: 0.5rem;
  padding-bottom: 0.5rem;
}

.uk-form-controls {
  margin-left: 0 !important;
}
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var,
b, i,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
    margin:0;
    padding:0;
    border:0;
    outline:0;
    font-size:100%;
    vertical-align:baseline;
    background:transparent;
}

body {
    line-height:1;
}

article,aside,details,figcaption,figure,
footer,header,hgroup,menu,nav,section { 
    display:block;
}

nav ul {
    list-style:none;
}

blockquote, q {
    quotes:none;
}

blockquote:before, blockquote:after,
q:before, q:after {
    content:’’;
    content:none;
}

a {
    margin:0;
    padding:0;
    font-size:100%;
    vertical-align:baseline;
    background:transparent;
}

/* change colours to suit your needs */
ins {
    background-color:#ff9;
    color:#000;
    text-decoration:none;
}

/* change colours to suit your needs */
mark {
    background-color:#ff9;
    color:#000; 
    font-style:italic;
    font-weight:bold;
}

del {
    text-decoration: line-through;
}

abbr[title], dfn[title] {
    border-bottom:1px dotted;
    cursor:help;
}

table {
    border-collapse:collapse;
    border-spacing:0;
}

/* change border colour to suit your needs */
hr {
    display:block;
    height:1px;
    border:0;   
    border-top:1px solid #cccccc;
    margin:1em 0;
    padding:0;
}

input, select {
    vertical-align:middle;
}
import { Component, OnInit } from '@angular/core';
import { SecurityService } from './data.service';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Component({
  selector: 'app-root',
  template: `<div [innerHtml] = "safeValue"></div>`,
  providers: [SecurityService]
})
export class AppComponent implements OnInit {
  safeValue: SafeHtml;
  constructor(private secure: SecurityService) {
    this.safeValue = this.secure.getSafeHtml("<h1>Sanitization Success</h1>");
  }
  ngOnInit() {
  }
}
import { Directive, ElementRef, HostBinding, HostListener } from "@angular/core";

@Directive({
    selector: '[appDropdown]'
})

export class DropdownDirective {
@HostBinding('class.open') isActive = false;

@HostListener('document:click', ['$event']) onClick(event: Event) {
        this.isActive = this.elRef.nativeElement.contains(event.target) ? !this.isActive : false;
    }

    constructor(private elRef: ElementRef) {}
}
import { Directive, ElementRef, Renderer } from '@angular/core';

@Directive({
    selector: '[appChbgcolor]'
})
export class ChangeBgColorDirective {

    constructor(private el: ElementRef, private renderer: Renderer) {
        this.ChangeBgColor('red');
    }

    ChangeBgColor(color: string) {

        this.renderer.setElementStyle(this.el.nativeElement, 'color', color);
    }
}
ng g module /main/customer --module=app --route=customer --routing=true
Hello, I can work on your Angular projects. I have already worked on angular and developed some merchandizing, ecommerce and educational web apps and also dashboards. I can work on different angular versions from Angularjs to Angular11.
I am also fullstack developer, if you will have anything from backend then it will be of no problem. just leave me a message and i will get back to you.
thank you.
`Pomoci zpětné uvozovky vytvoříte speciální řetězec, který lze psát na více 
 řádků a dají se do něj vkládat výrazy ${ 1+2 }, proměnné ${ x+y }, pole ${ seznam[0] },
 objekty ${ uzivatelske.jmeno } a dokonce ihned volané funkce ${ function() { return x+y; }() } 
 nebo metody ${ "sidon".toUpperCase() }.`
@ViewChild('main', {static: false}) main: ElementRef;

  constructor() {}

  skipLink() {
    this.main.nativeElement.focus()
    }
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { isDevMode, NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';

import { AngularFireModule } from '@angular/fire';
import { AngularFireStorageModule } from '@angular/fire/storage';

import {
  AngularFireAnalyticsModule,
  DEBUG_MODE as ANALYTICS_DEBUG_MODE,
  ScreenTrackingService,
  UserTrackingService
} from '@angular/fire/analytics';

import { FirestoreComponent } from './firestore/firestore.component';

import { AngularFireDatabaseModule, URL as DATABASE_URL } from '@angular/fire/database';
import { AngularFireAuthModule } from '@angular/fire/auth';
import { AngularFirestoreModule, SETTINGS as FIRESTORE_SETTINGS } from '@angular/fire/firestore';
import { AngularFireMessagingModule } from '@angular/fire/messaging';
import { AngularFireFunctionsModule, ORIGIN as FUNCTIONS_ORIGIN } from '@angular/fire/functions';
import { AngularFireRemoteConfigModule, SETTINGS as REMOTE_CONFIG_SETTINGS } from '@angular/fire/remote-config';
import { AngularFirePerformanceModule, PerformanceMonitoringService } from '@angular/fire/performance';
import { AngularFireAuthGuardModule } from '@angular/fire/auth-guard';
import { DatabaseComponent } from './database/database.component';
import { StorageComponent } from './storage/storage.component';
import { RemoteConfigComponent } from './remote-config/remote-config.component';
import { HomeComponent } from './home/home.component';
import { AuthComponent } from './auth/auth.component';
import { MessagingComponent } from './messaging/messaging.component';

const shouldUseEmulator = () => false;

@NgModule({
  declarations: [
    AppComponent,
    StorageComponent,
    FirestoreComponent,
    DatabaseComponent,
    RemoteConfigComponent,
    HomeComponent,
    AuthComponent,
    MessagingComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    BrowserTransferStateModule,
    AppRoutingModule,
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireStorageModule,
    AngularFireAnalyticsModule,
    AngularFireAuthModule,
    AngularFireDatabaseModule,
    AngularFirestoreModule.enablePersistence({ synchronizeTabs: true }),
    AngularFireMessagingModule,
    AngularFireFunctionsModule,
    AngularFireRemoteConfigModule,
    AngularFirePerformanceModule,
    AngularFireAuthGuardModule
  ],
  providers: [
    UserTrackingService,
    ScreenTrackingService,
    PerformanceMonitoringService,
    {
      provide: ANALYTICS_DEBUG_MODE,
      useFactory: () => isDevMode()
    },
    {
      provide: DATABASE_URL,
      useFactory: () => shouldUseEmulator() ? `http://localhost:9000?ns=${environment.firebase.projectId}` : undefined
    },
    { provide: FIRESTORE_SETTINGS, useFactory: () => shouldUseEmulator() ? { host: 'localhost:8080', ssl: false } : {} },
    { provide: FUNCTIONS_ORIGIN, useFactory: () => shouldUseEmulator() ? 'http://localhost:9999' : undefined },
    { provide: REMOTE_CONFIG_SETTINGS, useFactory: () => isDevMode() ? { minimumFetchIntervalMillis: 10_000 } : {} }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}
    this.form.controls.txtName.valueChanges.subscribe((value) => {
	// Logic here

    });
star

Sun Oct 29 2023 05:31:07 GMT+0000 (Coordinated Universal Time) https://www.vudu.com/js/vudu_common.js?single

#angular
star

Fri Sep 22 2023 05:54:37 GMT+0000 (Coordinated Universal Time) https://www.infragistics.com/community/blogs/b/infragistics/posts/simplest-way-to-share-data-between-two-unrelated-components-in-angular

#angular
star

Fri Sep 22 2023 05:54:04 GMT+0000 (Coordinated Universal Time) https://www.infragistics.com/community/blogs/b/infragistics/posts/simplest-way-to-share-data-between-two-unrelated-components-in-angular

#angular
star

Fri Sep 22 2023 05:53:10 GMT+0000 (Coordinated Universal Time) https://www.infragistics.com/community/blogs/b/infragistics/posts/simplest-way-to-share-data-between-two-unrelated-components-in-angular

#angular
star

Tue Sep 05 2023 15:37:13 GMT+0000 (Coordinated Universal Time) https://www.truecodex.com/course/angular-6/cascading-or-dependent-dropdown-list-country-state-city-in-angular-6-7

#ts #angular
star

Tue Sep 05 2023 15:36:19 GMT+0000 (Coordinated Universal Time) https://www.truecodex.com/course/angular-6/cascading-or-dependent-dropdown-list-country-state-city-in-angular-6-7

#html #angular
star

Tue Sep 05 2023 15:35:36 GMT+0000 (Coordinated Universal Time) https://www.truecodex.com/course/angular-6/cascading-or-dependent-dropdown-list-country-state-city-in-angular-6-7

#ts #angular
star

Sun Jul 02 2023 19:03:51 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/38008334/angular-rxjs-when-should-i-unsubscribe-from-subscription/41177163#41177163

#javascript #angular #rxjs
star

Fri Jun 23 2023 09:36:30 GMT+0000 (Coordinated Universal Time)

#rasa #angular
star

Fri Jun 23 2023 08:28:45 GMT+0000 (Coordinated Universal Time)

#c# #asp.net #identities #angular
star

Fri Jun 23 2023 08:28:00 GMT+0000 (Coordinated Universal Time)

#c# #asp.net #identities #angular
star

Fri Jun 23 2023 08:26:17 GMT+0000 (Coordinated Universal Time)

#c# #asp.net #identities #angular
star

Fri Jun 23 2023 08:16:17 GMT+0000 (Coordinated Universal Time)

#ionic #typescript #angular
star

Fri Jun 23 2023 08:12:30 GMT+0000 (Coordinated Universal Time)

#ionic #typescript #angular
star

Fri Jun 23 2023 08:11:25 GMT+0000 (Coordinated Universal Time)

#ionic #typescript #angular
star

Fri Jun 23 2023 08:10:19 GMT+0000 (Coordinated Universal Time)

#ionic #typescript #angular
star

Fri Jun 23 2023 08:09:24 GMT+0000 (Coordinated Universal Time)

#ionic #typescript #angular
star

Fri Jun 23 2023 08:06:46 GMT+0000 (Coordinated Universal Time)

#ionic #typescript #angular
star

Fri Jun 23 2023 08:05:05 GMT+0000 (Coordinated Universal Time)

#ionic #typescript #angular
star

Mon May 22 2023 07:23:37 GMT+0000 (Coordinated Universal Time) https://devzilla.io/using-nodejs-14-with-mac-silicon-m1

#typescript #javascript #angular
star

Wed May 03 2023 10:56:40 GMT+0000 (Coordinated Universal Time) https://maticz.com/trust-wallet-clone-app

#angular
star

Fri Apr 28 2023 09:15:25 GMT+0000 (Coordinated Universal Time) https://maticz.com/copy-trading-software

#angular
star

Mon Apr 17 2023 07:08:34 GMT+0000 (Coordinated Universal Time) https://maticz.com/bitcoin-escrow-script

#angular
star

Fri Apr 14 2023 09:53:55 GMT+0000 (Coordinated Universal Time)

#angular #pipe
star

Tue Apr 04 2023 12:36:52 GMT+0000 (Coordinated Universal Time) https://maticz.com/trust-wallet-clone-app

#angular
star

Fri Mar 31 2023 10:56:20 GMT+0000 (Coordinated Universal Time) https://maticz.com/cryptocurrency-business-ideas

#angular
star

Thu Mar 23 2023 04:58:55 GMT+0000 (Coordinated Universal Time) https://chat.openai.com/chat

#angular
star

Thu Mar 16 2023 05:34:40 GMT+0000 (Coordinated Universal Time) https://chat.openai.com/chat

#angular
star

Wed Mar 15 2023 07:34:52 GMT+0000 (Coordinated Universal Time) https://chat.openai.com/chat

#angular
star

Wed Mar 15 2023 07:34:29 GMT+0000 (Coordinated Universal Time) https://chat.openai.com/chat

#angular
star

Fri Mar 03 2023 05:50:05 GMT+0000 (Coordinated Universal Time) https://maticz.com/binance-clone-script

#angular
star

Tue Feb 21 2023 05:47:10 GMT+0000 (Coordinated Universal Time)

#angular
star

Mon Feb 20 2023 04:12:17 GMT+0000 (Coordinated Universal Time)

#angular
star

Mon Feb 20 2023 04:12:16 GMT+0000 (Coordinated Universal Time)

#angular
star

Thu Feb 09 2023 18:31:09 GMT+0000 (Coordinated Universal Time) https://medium.com/gitconnected/bad-practices-you-should-avoid-with-angular-development-58098e5542d5

#angular #rxjs-pattern
star

Wed Feb 01 2023 15:08:26 GMT+0000 (Coordinated Universal Time) https://youtu.be/VhEfoK5ypg4?t=952

#angular #rxjs-pattern
star

Wed Feb 01 2023 15:00:16 GMT+0000 (Coordinated Universal Time) https://youtu.be/rQTSMbeqv7I?t=1076

#angular #rxjs-pattern
star

Sun Jan 22 2023 02:07:21 GMT+0000 (Coordinated Universal Time)

#angular #rxjs-pattern
star

Sun Jan 22 2023 00:14:43 GMT+0000 (Coordinated Universal Time)

#angular #rxjs-pattern
star

Sat Jan 21 2023 08:03:25 GMT+0000 (Coordinated Universal Time) https://youtu.be/SXOZaWLs4q0?t=740

#angular #rxjs-pattern
star

Fri Jan 20 2023 05:06:51 GMT+0000 (Coordinated Universal Time)

#angular #rxjs-pattern
star

Tue Jan 10 2023 00:17:40 GMT+0000 (Coordinated Universal Time) https://danielk.tech/pt-br/como-ter-uma-nova-tentativa-de-requisicao-http-no-angular-varios-codigos-como-exemplo

#angular #rxjs-pattern
star

Fri Jan 06 2023 21:05:59 GMT+0000 (Coordinated Universal Time)

#angular #rxjs-pattern
star

Tue Jan 03 2023 06:07:16 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/38571812/how-to-detect-when-an-input-value-changes-in-angular

#angular #rxjs-pattern
star

Thu Dec 29 2022 03:15:25 GMT+0000 (Coordinated Universal Time) https://youtu.be/-N6ZrGh2bjc?t=595

#angular #rxjs-pattern
star

Thu Dec 29 2022 02:43:10 GMT+0000 (Coordinated Universal Time)

#angular #rxjs-pattern
star

Thu Dec 29 2022 02:42:35 GMT+0000 (Coordinated Universal Time) https://angular.io/api/router/Resolve

#angular #rxjs-pattern
star

Mon Dec 26 2022 23:12:54 GMT+0000 (Coordinated Universal Time) https://youtu.be/qxjt5vlG58s?t=2309

#angular #rxjs-pattern
star

Mon Dec 26 2022 19:44:12 GMT+0000 (Coordinated Universal Time)

#angular #rxjs-pattern
star

Mon Dec 26 2022 19:37:43 GMT+0000 (Coordinated Universal Time) https://youtu.be/SPy35fOjRyU?t=557

#angular #rxjs-pattern
star

Mon Dec 26 2022 19:15:03 GMT+0000 (Coordinated Universal Time) https://youtu.be/SPy35fOjRyU?t=133

#angular #rxjs-pattern
star

Mon Dec 26 2022 18:00:11 GMT+0000 (Coordinated Universal Time) https://youtu.be/bqIj-m7Uxzk?t=1039

#angular #rxjs-pattern
star

Mon Dec 26 2022 04:26:01 GMT+0000 (Coordinated Universal Time) https://youtu.be/IxOBrYUxetc?t=953

#angular #rxjs-pattern
star

Sat Dec 24 2022 03:27:55 GMT+0000 (Coordinated Universal Time) https://youtu.be/eWU2vlohOwQ?t=734

#angular #rxjs-pattern
star

Fri Dec 23 2022 16:36:37 GMT+0000 (Coordinated Universal Time) https://youtu.be/B-nFj2o03i8?t=821

#angular #rxjs-pattern
star

Wed Dec 21 2022 15:33:13 GMT+0000 (Coordinated Universal Time)

#angular #rxjs-pattern
star

Wed Dec 21 2022 15:26:38 GMT+0000 (Coordinated Universal Time)

#angular #rxjs-pattern
star

Sat Dec 17 2022 03:51:27 GMT+0000 (Coordinated Universal Time)

#angular
star

Sat Dec 17 2022 03:32:48 GMT+0000 (Coordinated Universal Time) https://www.youtube.com/watch?v=uv_sblwIJag&t=232s

#angular
star

Fri Dec 16 2022 16:46:38 GMT+0000 (Coordinated Universal Time)

#angular
star

Fri Dec 16 2022 16:19:38 GMT+0000 (Coordinated Universal Time) https://youtu.be/uv_sblwIJag?t=221

#angular #rxjs
star

Thu Nov 03 2022 23:19:58 GMT+0000 (Coordinated Universal Time)

#angular
star

Wed Oct 19 2022 10:27:20 GMT+0000 (Coordinated Universal Time) https://maticz.com/token-development

#nodejs #angular #javascript #php #python #vue.js #react.js
star

Wed Oct 19 2022 10:25:51 GMT+0000 (Coordinated Universal Time) https://maticz.com/how-to-create-nft-marketplace

#javascript #java #laravel #angular
star

Wed Oct 19 2022 10:19:52 GMT+0000 (Coordinated Universal Time) https://bit.ly/3GLa8p1

#javascript #java #php #laravel #angular #nodejs
star

Thu Sep 29 2022 14:30:05 GMT+0000 (Coordinated Universal Time)

#angular
star

Thu Sep 22 2022 13:57:05 GMT+0000 (Coordinated Universal Time)

#angular
star

Thu Sep 22 2022 13:21:00 GMT+0000 (Coordinated Universal Time)

#angular
star

Thu Sep 22 2022 13:00:11 GMT+0000 (Coordinated Universal Time)

#angular
star

Sat Sep 17 2022 11:23:29 GMT+0000 (Coordinated Universal Time)

#typescript #angular
star

Mon Jul 11 2022 18:59:17 GMT+0000 (Coordinated Universal Time) https://rustwasm.github.io/docs/book/game-of-life/hello-world.html

#rust #wasm #wasm-pack #angular
star

Fri Jun 24 2022 14:41:35 GMT+0000 (Coordinated Universal Time)

#bash #ionic #angular #capacitor #qrcode #reader #css
star

Fri Jun 24 2022 14:39:58 GMT+0000 (Coordinated Universal Time)

#bash #ionic #angular #capacitor #qrcode #reader #javascript
star

Fri Jun 24 2022 14:38:23 GMT+0000 (Coordinated Universal Time)

#bash #ionic #angular #capacitor
star

Wed Jun 22 2022 13:16:39 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/48048299/angular-5-scroll-to-top-on-every-route-click

#angular
star

Mon Jun 20 2022 18:31:51 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/66014183/error-when-installing-ng-add-ng-bootstrap-ng-bootstrap

#angular
star

Thu Jun 16 2022 08:44:09 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/46469349/how-to-make-an-angular-module-to-ignore-http-interceptor-added-in-a-core-module

#angular
star

Mon May 16 2022 14:27:31 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/65966720/error-ts2531-object-is-possibly-null-in-angular-reactive-forms

#angular
star

Mon May 16 2022 14:18:04 GMT+0000 (Coordinated Universal Time) https://laracasts.com/discuss/channels/javascript/oh-reallyproperty-form-has-no-initializer-and-is-not-definitely-assigned-in-the-constructor-property-createcomponentform-formgroup

#angular
star

Tue Dec 07 2021 23:31:50 GMT+0000 (Coordinated Universal Time) https://shrutibalasa.hashnode.dev/install-and-setup-tailwind-css-2-with-angular-11

#webpack #angular #tailwindcss
star

Wed Sep 01 2021 14:34:55 GMT+0000 (Coordinated Universal Time)

#html #angular #json
star

Wed Sep 01 2021 13:15:41 GMT+0000 (Coordinated Universal Time)

#html #angular #json
star

Wed Sep 01 2021 12:56:32 GMT+0000 (Coordinated Universal Time)

#html #angular #json
star

Wed Sep 01 2021 12:23:58 GMT+0000 (Coordinated Universal Time)

#html #angular #json
star

Sun Jun 27 2021 07:14:31 GMT+0000 (Coordinated Universal Time)

#angular
star

Tue Jun 22 2021 14:58:33 GMT+0000 (Coordinated Universal Time)

#angular
star

Sun Jun 13 2021 15:38:33 GMT+0000 (Coordinated Universal Time)

#angular #typescript
star

Sun Jun 13 2021 15:37:36 GMT+0000 (Coordinated Universal Time)

#angular #typescript
star

Tue May 04 2021 01:13:44 GMT+0000 (Coordinated Universal Time)

#angular #typescript
star

Sat May 01 2021 18:31:57 GMT+0000 (Coordinated Universal Time)

#angular #typescript
star

Mon Apr 26 2021 03:40:13 GMT+0000 (Coordinated Universal Time)

#angular #commandline
star

Sun Mar 28 2021 18:02:24 GMT+0000 (Coordinated Universal Time)

#angular
star

Tue Mar 16 2021 15:07:01 GMT+0000 (Coordinated Universal Time)

#javascript #angular
star

Tue Mar 16 2021 13:28:35 GMT+0000 (Coordinated Universal Time)

#typescript #angular
star

Sun Mar 07 2021 08:22:25 GMT+0000 (Coordinated Universal Time) https://www.syncfusion.com/blogs/post/top-5-best-practices-angular-app-security.aspx

#angular #security
star

Fri Feb 26 2021 10:42:08 GMT+0000 (Coordinated Universal Time)

#typescript #angular
star

Thu Feb 25 2021 09:51:42 GMT+0000 (Coordinated Universal Time)

#typescript #javascript #angular
star

Mon Feb 22 2021 09:26:38 GMT+0000 (Coordinated Universal Time)

#angular
star

Fri Jan 01 2021 06:32:12 GMT+0000 (Coordinated Universal Time)

#angular
star

Thu Nov 26 2020 01:31:12 GMT+0000 (Coordinated Universal Time)

#javascript #typescript #angular #react.js
star

Sun Nov 08 2020 08:59:40 GMT+0000 (Coordinated Universal Time)

#angular
star

Fri Oct 23 2020 10:04:57 GMT+0000 (Coordinated Universal Time) https://github.com/angular/angularfire/blob/master/sample/src/app/app.module.ts

#angular #javascript
star

Sat Jul 11 2020 07:29:29 GMT+0000 (Coordinated Universal Time)

#angular
star

Tue May 26 2020 16:45:33 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/extension/initializing

#angular

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension