setTimeout() – async / await – Typescript / Angular application

Wait for component load with less time possible. (draft)

Abstract

I have angular app with registered components linked in some Map objects…

Others services and/or components need, on startup, to check if one or more components are registered and, if not, throw an exception.

Problem

On startup when checks if component exists one exception is generate because component is not completely load.

first solution …setTimeout

incapsulate check function/s into setTimeout and wait 1s (1000 ms) or even 2s; but if the function is called 5, 10 or even 20 times, we must wait for 20 or, even, 40 seconds …
… even if about 80% are already load…

second solution … async / await with timeout

With only await the risk is to wait a component that will never be load (es: classic typing error -> wait debugcomp but real component name is debugComp) and app freeze.

my solution … async / await with timeout

Probably not the better solution but work quite well…

The idea is setting a max timeout, es: 3s, set timeout interval, es: 50ms:

  • await check function max 3s
  • check function every 50ms test if component exists
    • if not exists call itself after 50ms
    • if component is load -> resolve Promise
    • if after 3s component not exists break loop and resolve Promise and probably throw new error
typescript code in angular class
// class function
async myFunc(mypar: any) {
    try {
      // ... your code
      const test = await this.awaitresolve(par1, par2, ..., 3000);

      if (!test) {
        // not test throw exception
        throw new Error('Your test failed');
      }
      // ... your code
   }
}

this.awaitresolve

awaitresolve(par1, par2, ..., timeout: number): Promise<myObject> {
    return new Promise((resolve, reject) => {

      const interval = 50;
      const targetcheck = myresult2test // es: mymap.get(par1);
      // new timeout setting es: form 3000 to 2950
      const newtimeout = timeout - interval;

      if (!targetcheck && timeout > 0) {
        // not checked
        setTimeout(() => {
          resolve(
            this.awaitresolve(par1, par2, ..., newtimeout)
          )
        }, interval);  // <-- only 50ms
      } else {
        // exist in mymap
        resolve(targetcheck as myObject);
      }
    });
  }

At the moment this code is not tested in production environments but will be asap in the future.

Probably evolution will be merge in FIFO queue to manage events driven app.

robots.txt directly from nginx

I have some websites published on public ip, for accessibility, but for my customers internal, private, use.
For this websites we don’t need search engines indexing.
But every time that I upload to remote new version, I delete robots.txt and, sometime, I forget to rewrite it.

We don’t need indexing so robots.txt is a very, very complex file, simply stop all crawler …

User-agent: *
Disallow: /

So why not serve it directly from nginx? without add real file?

After a little I found a good example on serverfault and I modified all my nginx server blocks:

server {
  listen myport;
  root /my/www/root;
  server_name your.site.dot
  ...
  location = /robots.txt {
   add_header Content-Type text/plain;
   return 200 "User-agent: *\nDisallow: /\n";
  }
  ...
}

… now we can delete robots.txt from my web root and test it.

tips

to test remember to disable browser cache or use curl -v https://your.site.dot/robots.txt

Angular + ngx-admin (draft)

+ ngx-admin

Oltre un’anno fa, stavo cercando una ‘dashboard’ nativa angular e non un port da jquery, per un sviluppare un progetto client/server (postgresql, php, web, client), che permettesse di concentrarsi più sulla ‘gestione dei dati’, cosa realmente importante, che sullo sviluppo interfaccia ma… anche l’occhio vuole la sua parte.
Dopo un po’ di ricerche ho deciso, di concentrarmi su un prodotto già preso in considerazione in passato ma poi, un po’ per tempo un po’ per pigrizia, avevo abbandonato: ngx-admin.
Se, come me, siete pigri ma curiosi esiste una demo online che vi permetterà immediatamente di valutare se fa al caso vostro.
… e se siete sviluppatori bravi e sapete bene l’inglese, non come me, potete anche farvi contattare ed esporre i vostri quesiti.

ngx-admin è basato su nebular e eva icon, comprese in ngx, insieme formano eva-design, commerciale; ma se fosse necessario, è possibile partire da zero… ma il target, al momento, è quello di mostrare gli stessi dati con un vestito nuovo, e piacevole…


premessa

Sono appunti presi come promemoria visto che è stato deciso di ‘ridisegnare’ tutto il prodotto, attualmente in produzione per migliorarlo; sicuramente, questo metodo non è l’unico ne il migliore e/o corretto, ma funziona…

Per lo stesso motivo mi soffermo su installazioni varie, node, npm, git etc. e versioni richieste.

cosa serve

Come detto sopra indico cosa utilizzo:

  • Visual Studio Code con remote ssh perchè il progetto è su una macchina virtuale linux
  • su vm linux node e npm aggiornati, preferibilmente

setup ambiente

Come nelle indicazioni ufficiali creo un cartella per il progetto

$ mkdir ngx-admin7-ng12
$ cd ngx-admin7-ng12

clono ngx-admin

git clone https://github.com/akveo/ngx-admin.git

per avere diverse versioni nello stesso folder rinomino (mia idea) cartella generata e faccio partire installazione, installa anche angular:

$ mv ngx-admin ngx-admin7-ng12
$ cd ngx-admin7-ng12 && npm i

Adesso o apro un nuovo progetto su VisualCode oppure se voglio unirlo a un workspace esistente in VisualCode apro il mio file .code-workspace e aggiungo

{
  "path": "my root path /ngx-admin7-ng12"
},

adesso posso continuare in VisualCode, mi posiziono su ngx-admin7-ng12 click destro e ‘Open In Integrated Terminal’ dal terminale aperto, faccio fix npm, per allineare versioni etc. e faccio prima prova partenza

$ npm audit fix
$ npm start

Se tutto su stesso ambiente e tutto corretto http://localhost:4200 si apre demo.
Per comodità utilizzo un proxy, ma comunque, accedendo in remoto browser da eerrore e non arica;
modifico package.json aggiungendo a ng serve –disable-host-check, che non controlla ip provenienza;
ng serve genera warning ma ssendo in intranet non interessa, in produzione evitare.

Ma se tutto andato bene adesso ngx-admin gira nell’ambiente privato e potete provare e modificare.

updating Angular

Al momento ngx-admin v.7 installa angular 11 quindi posso anche aggiornare versione quindi da update angular

$ ng update @angular/core@12 @angular/cli@12

se ci sono problemi on versioni node, come nel mio caso

aggiorniamo node con nvm come illustrato

$ sudo apt update
$ sudo apt install build-essential checkinstall libssl-dev
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.1/install.sh | bash
$ nvm –version /* chiudo e riapro terminale prima */
$ nvm ls /* versioni locali */
$ nvm ls-remote. /* versioni disponibili */
$ nvm install [version.number]

se la demo è su una subdir web

ng build –prod –base-href /tuasubdir/

todo … update e auth

page, ng-content & select

page.component src/app/pages/pages.component.ts è il componente principale, contiene il blocco principale layout:

originale

@Component({
  selector: 'ngx-pages',
  styleUrls: ['pages.component.scss'],
  template: `
    <ngx-one-column-layout>
      <nb-menu [items]="menu"></nb-menu>
      <router-outlet></router-outlet>
    </ngx-one-column-layout>
  `,
})

modificato

@Component({
  selector: 'ngx-pages',
  styleUrls: ['pages.component.scss'],
  template: `
    <ngx-gisp-tablet-layout>
      <nb-menu [items]="menu" tag="left-menu"></nb-menu>
      <router-outlet></router-outlet>
      <nb-menu [items]="menu" tag="right-menu"></nb-menu>
    </ngx-gisp-tablet-layout>
  `,
})

Nella modifica duplico menu, uno a dx e uno sx, dove aggiungo tag che richiamo <ng-content select="[tag=left-menu]"></ng-content>

angular multiple router-outlet

Come idea per ogni route dovrò avere diversi menu a dx e sx, come documentazione parto da tutorial techdiaries e multiple outlets

elenco promemoria

  • https://angular.io/api/router/RouterOutlet
  • https://blog.angular-university.io/angular2-router/
  • https://www.techiediaries.com/routing-angular-router/
  • https://www.techiediaries.com/angular-router-multiple-outlets/
  • http://guodongh.ca/2019/08/24/Angular-8-Content-Projection-Router-Pipe-and-Dependency-Injection/
  • https://angular.io/guide/view-encapsulation
  • https://stackoverflow.com/questions/42315058/ng-content-vs-router-outlet-in-angular-2
  • https://stackoverflow.com/questions/51105244/my-angular-app-needs-two-columns-but-the-content-of-those-can-vary-significantl
  • (content projection) https://medium.com/disney-streaming/content-projection-with-angular-dbc61c6c181