Geekle.us – Free Online Tech Conference 2 April 2020

We can use this period of quarantine to stay at home and study something of new.
At the 2 April there will be an online tech conference about DevOps and JS at the 11:00 AM CET on www.geekle.us.

The Conference is free and you can register on the bottom site, through eventbrite

The event is divided into 2 Track, One about DevOps and One about JS

TRACK #1 TRACK #2
11:00 AMSenior DevOps Section React.js Section
Azure DevOps and GitHub ActionsMaintainable React
Infrastructure as Code on AWS: Deep DiveHow to build your reusable UI
component library like a pro
Build and deploy a serverless
web app on GCP
End to end testing a world of web,
mobile & desktop apps
13:40 AMJunior DevOps Section Node.js Section
Topik
(Coming soon)
Callbacks to Async/Await in Node.js
+ Build you own promise
Automating your first infrastructure with Terraform on AWS Finding memory leaks and CPU bottlenecks
with Node.js debug tools
Observability in DevOps Malicious Modules on npm – a series of unfortunate events
16:10 AMSoft Skills Section
Working from home –
how to not kill relationships
Modern Stoicism: How practice discipline
and stay calm during the crisis.

I think that will be interesting the final section about the Soft Skill and how to not kill relationships while we stay at home.

And so.. let’s go to subscribe on geekle.us event!

QuaggaJS Barcode Scanner Setting EAN13 Code128

Today is very important the use of smartphone / table for work. 
And in many case is important to read barcode or qrcode.

For that, now i want to speak about QuaggaJS a javascript library for reading barcode.
I have used it and setting up for a correct mobile resize of video stream, and for reading code128 and ean13.

At first we must to download it from the website: https://serratus.github.io/quaggaJS/

Install

  1. At first we must to download it from the website: https://serratus.github.io/quaggaJS/
  2. Read the guide about installation https://serratus.github.io/quaggaJS/#installing

Example Page

CSS responsive

#interactive.viewport {
    position: relative;
}

#interactive.viewport > canvas, #interactive.viewport > video {
    max-width: 100%;
    width: 100%;
}

canvas.drawing, canvas.drawingBuffer {
    position: absolute;
    left: 0;
    top: 0;
}
  
@media (max-width: 603px) {

  .reader-config-group {
    width: 100%;
  }

  .reader-config-group label > span {
      width: 50%;
  }

  .reader-config-group label > select, .reader-config-group label > input {
      max-width: calc(50% - 2px);
  }

  #interactive.viewport {
    width: 100%;
    height: auto;
    overflow: hidden;
  }
}

HTML

<div class="card">
    <div class="card-body">
        <div class="row">
          <div class="col-xs-12 col-sm-12 col-md-6">
            <div id="interactive" class="viewport"></div>
          </div>
          <div class="col-xs-12 col-sm-12 col-md-6">
            <div id="result_strip">
          </div>
         </div>
        </div>
    </div>
  </div>

JAVASCRIPT

var AppQuagga = {
    init: function() {
        var self = this;

        Quagga.init(this.state, function(err) {
            if (err) {
                return self.handleError(err);
            }
            //Quagga.registerResultCollector(resultCollector);
            Quagga.start();

            Quagga.onProcessed(function(result) {
                var drawingCtx = Quagga.canvas.ctx.overlay,
                    drawingCanvas = Quagga.canvas.dom.overlay;

                if (result) {
                    if (result.boxes) {
                        drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
                        result.boxes.filter(function (box) {
                            return box !== result.box;
                        }).forEach(function (box) {
                            Quagga.ImageDebug.drawPath(box, {x: 0, y: 1}, drawingCtx, {color: "green", lineWidth: 2});
                        });
                    }

                    if (result.box) {
                        Quagga.ImageDebug.drawPath(result.box, {x: 0, y: 1}, drawingCtx, {color: "#00F", lineWidth: 2});
                    }

                    if (result.codeResult &amp;&amp; result.codeResult.code) {
                        Quagga.ImageDebug.drawPath(result.line, {x: 'x', y: 'y'}, drawingCtx, {color: 'red', lineWidth: 3});
                    }
                }
            });

            setTimeout(function() {
              var track = Quagga.CameraAccess.getActiveTrack();
              var capabilities = {};
              if (typeof track.getCapabilities === 'function') {
                try
                  {
                 capabilities = track.getCapabilities(); 
                 track.applyConstraints({advanced: [{zoom: 2.5}]});
                  } catch(e) {}
              }
            }, 500);
        });
    },
    handleError: function(err) {
        console.log(err);
    },
    state: {
        inputStream: {
            type : "LiveStream",
            constraints: {
                facingMode: "environment"
            }
        },
        locator: {
            patchSize: "medium",
            halfSample: true
        },
        numOfWorkers: (navigator.hardwareConcurrency ? navigator.hardwareConcurrency : 4),
        frequency: 20,
        decoder: {
            readers : [{
                format: "code_128_reader",
                config: {}
            }, {
                format: "ean_reader",
                config: {
                }
            }, {
                format: "code_39_reader",
                config: {}
            }, {
                format: "code_93_reader",
                config: {}
            }]
        },
        locate: true
    },
    lastResult : null
};



AppQuagga.init();
      
Quagga.onDetected(function(result) {
	var code = result.codeResult.code;

	if(code != null) {
		if (AppQuagga.lastResult !== code) {
			AppQuagga.lastResult = code;

			var $node = null;
			$node = $('<p>Read: '+code+'</p>');
			$("#result_strip").prepend($node);
		}
	}
});

This piece of code is for zoom, and the timeout attend that the videocamera open itself.
For the zoom you can set the max with: capabilities.zoom.max

setTimeout(function() {
  var track = Quagga.CameraAccess.getActiveTrack();
  var capabilities = {};
  if (typeof track.getCapabilities === 'function') {
	try
	  {
	 capabilities = track.getCapabilities(); 
	 track.applyConstraints({advanced: [{zoom: 2.5}]});
	  } catch(e) {}
  }
}, 500);

React how to convert Class to Hooks tutorial

The Hooks are a functional component that simplify the use of React, and allow use to create some reusable component.

I have changed on my TodoList App a class to a Hooks

The React Class

class TodoListElementDelete extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      index: 0,
      timer: 0,
      _timeoutRef: null
    };

    this.onClickUndoDelete = this.onClickUndoDelete.bind(this);
    
  }

  componentDidMount() {
    this.setState({
      index: this.props.index,
      timer: this.props.timer
    });
  }

  componentDidUpdate() {
    if (this.props.enable) {
      this.state._timeoutRef = setTimeout(() => {
        if (this.state.timer > 0) {
          this.setState({
            timer: this.state.timer - 1
          });
        } else {
          this.props.onEndTimerAction();
        }
      }, 1000);
    }
  }

  componentWillUnmount() {
    console.log("componentWillUnmount");
    clearTimeout(this.state._timeoutRef);
  }

  onClickUndoDelete() {
    clearTimeout(this.state._timeoutRef);
    this.setState({
      timer: this.props.timer
    });
    this.props.onClickUndoDelete();
  }

  render() {
    let classHideItem = this.props.enable ? "" : "hidden";
    return (
      <div className={"alert alert-danger " + classHideItem}>
        You want to undo the action? {this.state.timer}
        <button
          type="button"
          className="btn btn-warning"
          onClick={this.onClickUndoDelete}
        >
          Undo
        </button>
      </div>
    );
  }
}

React Hooks

I have changed a React Class with React Hooks:

  • timer managed with useState
  • _timeoutRef with useRef
  • ComponentDidMount, ComponentWillUnmount, ComponentDidUpdate with useEffect
const TodoListElementDelete = props => {
  const [timer, setTimer] = React.useState(props.timer);
  let _timeoutRef = React.useRef();

  function onClickUndoDelete() {
    clearTimeout(_timeoutRef.current);
    setTimer(props.timer);
    props.onClickUndoDelete();
  }

  React.useEffect(() => {
    if (props.enable) {
      _timeoutRef.current = setTimeout(() => {
        if (timer > 0) {
          setTimer(timer - 1);
        } else {
          props.onEndTimerAction();
        }
      }, 1000);
    }

    return () => clearTimeout(_timeoutRef.current);
  });

  return (
    <div className={`alert alert-danger ${props.enable ? "" : "hidden"}`}>
      You want to undo the action? {timer}
      <button
        type="button"
        className="btn btn-warning"
        onClick={onClickUndoDelete}
      >
        Undo
      </button>
    </div>
  );
};

30 Second to React – Collection of useful React snippets

Today i want to speak about this beautiful collection of React snippet that i found on github 

There are some useful function, in my opinion the most important are about the use of Hooks.

I report here the Hooks found on GitHub

Hooks

  • useFetch
  • useInterval
  • useNavigatorOnline
  • useTimeout

useFetch

A hook that implements fetch in a declarative manner.

  • Create a custom hook that takes a url and options.
  • Use the React.useState() hook to initialize the response and error state variables.
  • Use the React.useEffect() hook to anychronously call fetch() and update the state varaibles accordingly.
  • Return an object containting the response and error state variables.
const useFetch = (url, options) => {
  const [response, setResponse] = React.useState(null);
  const [error, setError] = React.useState(null);

  React.useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
      } catch (error) {
        setError(error);
      }
    };
    fetchData();
  }, []);

  return { response, error };
};

useInterval

A hook that implements setInterval in a declarative manner.

  • Create a custom hook that takes a callback and a delay.
  • Use the React.useRef() hook to create a ref for the callback function.
  • Use the React.useEffect() hook to remember the latest callback.
  • Use the React.useEffect() hook to set up the interval and clean up.
const useInterval = (callback, delay) => {
  const savedCallback = React.useRef();

  React.useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  React.useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
};

useNavigatorOnLine

A hook that returns if the client is online or offline.

  • Create a function, getOnLineStatus, that uses the NavigatorOnLine web API to get the online status of the client.
  • Use the React.useState() hook to create an appropriate state variable, status, and setter.
  • Use the React.useEffect() hook to add listeners for appropriate events, updating state, and cleanup those listeners when unmounting.
  • Finally return the status state variable.
const getOnLineStatus = () =>
  typeof navigator !== "undefined" &amp;&amp; typeof navigator.onLine === "boolean"
    ? navigator.onLine
    : true;

const useNavigatorOnLine = () => {
  const [status, setStatus] = React.useState(getOnLineStatus());

  const setOnline = () => setStatus(true);
  const setOffline = () => setStatus(false);

  React.useEffect(() => {
    window.addEventListener("online", setOnline);
    window.addEventListener("offline", setOffline);

    return () => {
      window.removeEventListener("online", setOnline);
      window.removeEventListener("offline", setOffline);
    };
  }, []);

  return status;
};

useTimeout

A hook that implements setTimeout in a declarative manner.

  • Create a custom hook that takes a callback and a delay.
  • Use the React.useRef() hook to create a ref for the callback function.
  • Use the React.useEffect() hook to remember the latest callback.
  • Use the React.useEffect() hook to set up the timeout and clean up.
const useTimeout = (callback, delay) => {
  const savedCallback = React.useRef();

  React.useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  React.useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setTimeout(tick, delay);
      return () => clearTimeout(id);
    }
  }, [delay]);
};

React Todo List with Undo Timer on Delete

Goodmorning, 
it’s more time that not write, i spent some time to study ReactJS, so i think that Angular is better, but so ReactJS has its “why”.
Today i want to show how create a simple React TodoList Example in which i have implemented a system to delete an item, but whit a “undo” (possibilities of recovery the deleted item), the undo has a timer (like gmail) to recover the deleted item.

So Let’s start!

Structure of our Component

We must to think as “React”, so we define our component composition:
– TodoList
— TodoListForm
— TodoListElement
— TodoListElementDelete

At first we must to create the class, and define it in src/components/TodoList.js

Attach all the code below, you can find the entire example on CodeSandBox

import React from "react";
import Header from "./Header";

class TodoListElementDelete extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      index: 0,
      timer: 0,
      _timeoutRef: null
    };

    this.onClickUndoDelete = this.onClickUndoDelete.bind(this);
  }

  componentDidMount() {
    this.setState({
      index: this.props.index,
      timer: this.props.timer
    });
  }

  componentDidUpdate() {
    if (this.props.enable) {
      this.state._timeoutRef = setTimeout(() => {
        if (this.state.timer > 0) {
          this.setState({
            timer: this.state.timer - 1
          });
        } else {
          this.props.onEndTimerAction();
        }
      }, 1000);
    }
  }

  componentWillUnmount() {
    console.log("componentWillUnmount");
    clearTimeout(this.state._timeoutRef);
  }

  onClickUndoDelete() {
    clearTimeout(this.state._timeoutRef);
    this.setState({
      timer: this.props.timer
    });
    this.props.onClickUndoDelete();
  }

  render() {
    let classHideItem = this.props.enable ? "" : "hidden";
    return (
      <div className={"alert alert-danger " + classHideItem}>
        You want to undo the action? {this.state.timer}
        <button
          type="button"
          className="btn btn-warning"
          onClick={this.onClickUndoDelete}
        >
          Undo
        </button>
      </div>
    );
  }
}

class TodoListElement extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isDeleted: this.props.item.isDeleted
    };
    this.onClickDelete = this.onClickDelete.bind(this);
    this.onClickUndoDelete = this.onClickUndoDelete.bind(this);
    this.onClickPermanentDelete = this.onClickPermanentDelete.bind(this);
    this.onClickComplete = this.onClickComplete.bind(this);
  }

  onClickDelete() {
    let index = parseInt(this.props.item.index);
    this.props.removeItem(index);
  }

  onClickUndoDelete() {
    let item = this.props.item;
    this.props.undoRemoveItem(item);
  }

  onClickPermanentDelete() {
    this.setState({
      isDeleted: true
    });
    //this.props.definitiveRemoveItem(index);
  }

  onClickComplete() {
    let index = parseInt(this.props.item.index);
    this.props.completeItem(index);
  }

  render() {
    let isCompletedClass = this.props.item.isCompleted
      ? "list-group-item-success"
      : "";

    const btnActionComplete = this.props.item.isCompleted ? (
      ""
    ) : (
      <button
        type="button"
        className="btn btn-success btn-sm"
        onClick={this.onClickComplete}
      >
        Complete
      </button>
    );

    const btnActionDelete = (
      <button
        type="button"
        className="btn btn-danger btn-sm"
        onClick={this.onClickDelete}
      >
        Delete
      </button>
    );

    isCompletedClass = this.state.isDeleted ? "hidden" : isCompletedClass;

    return (
      <li className={"list-group-item " + isCompletedClass}>
        <div className="clarfix">
          {this.props.item.value}
          <span className="float-right">
            {btnActionComplete}
            {btnActionDelete}
          </span>
        </div>
        <TodoListElementDelete
          index={this.props.item.index}
          timer={this.props.timer}
          enable={this.props.item.isBeingDeleted}
          onClickUndoDelete={this.onClickUndoDelete}
          onEndTimerAction={this.onClickPermanentDelete}
        />
      </li>
    );
  }
}

class TodoListForm extends React.Component {
  constructor(props) {
    super(props);
    this.onSubmit = this.onSubmit.bind(this);
  }

  onSubmit(event) {
    event.preventDefault();
    var newItemValue = this.refs.itemName.value;

    if (newItemValue) {
      this.props.addItem({ newItemValue });
      this.refs.form.reset();
    }
  }

  render() {
    return (
      <form ref="form" onSubmit={this.onSubmit} className="form-inline">
        <div className="input-group mb-3">
          <input
            type="text"
            className="form-control"
            ref="itemName"
            placeholder="Write todo item"
          />
          <div className="input-group-append">
            <button className="btn btn-success" type="submit">
              Add
            </button>
          </div>
        </div>
      </form>
    );
  }
}

export default class TodoList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      _lastIndex: 0,
      todoItems: [],
      undoRemoveItems: [],
      timer: 10
    };

    this.addItem = this.addItem.bind(this);
    this.removeItem = this.removeItem.bind(this);
    this.undoRemoveItem = this.undoRemoveItem.bind(this);
    this.definitiveRemoveItem = this.definitiveRemoveItem.bind(this);
    this.completeItem = this.completeItem.bind(this);
  }

  getNewIndex() {
    return this.state._lastIndex + 1;
  }

  addItem(todoItem) {
    const newTodoItem = {
      index: this.getNewIndex(),
      value: todoItem.newItemValue,
      isBeingDeleted: false,
      isDeleted: false,
      isCompleted: false
    };

    this.setState({
      todoItems: [...this.state.todoItems, newTodoItem],
      _lastIndex: newTodoItem.index
    });
  }

  removeItem(itemIndex) {
    let itemToBeDeleted = this.state.todoItems.find(x => x.index === itemIndex);
    if (itemToBeDeleted) {
      itemToBeDeleted.isBeingDeleted = true;
    }
    this.setState({ todoItems: this.state.todoItems });
  }

  definitiveRemoveItem(itemIndex) {
    console.log("definitiveRemoveItem", itemIndex);

    let todoItems = this.state.todoItems;
    let undoTodoItem = this.state.undoRemoveItems;
    let itemToBeDeleted = todoItems.find(
      x => x.index === itemIndex &amp;&amp; x.isBeingDeleted
    );
    let itemInUndo = undoTodoItem.find(x => x.index === itemIndex);
    if (itemToBeDeleted &amp;&amp; itemInUndo == null) {
      todoItems = todoItems.filter(x => x.index !== itemIndex);
    } else {
      undoTodoItem = undoTodoItem.filter(x => x.index !== itemIndex);
    }
    this.setState({
      todoItems: todoItems,
      undoRemoveItems: undoTodoItem
    });
  }

  undoRemoveItem(item) {
    let todoItems = this.state.todoItems;
    let itemToBeDeleted = todoItems.find(x => x.index === item.index);
    itemToBeDeleted.isBeingDeleted = false;
    this.setState({
      todoItems: todoItems
    });
  }

  completeItem(itemIndex) {
    let todoItems = this.state.todoItems;
    let itemComplete = todoItems.find(x => x.index === itemIndex);
    itemComplete.isCompleted = true;
    this.setState({
      todoItems: todoItems
    });
  }

  render() {
    let items = this.state.todoItems.map((item, index) => {
      return (
        <TodoListElement
          key={index}
          item={item}
          timer={this.state.timer}
          completeItem={this.completeItem}
          removeItem={this.removeItem}
          undoRemoveItem={this.undoRemoveItem}
          definitiveRemoveItem={this.definitiveRemoveItem}
        />
      );
    });

    return (
      <div>
        <Header />
        <div className="container">
          <TodoListForm addItem={this.addItem} />
          <ul className="list-group"> {items} </ul>
        </div>
      </div>
    );
  }
}

Do you have some suggestion about React programming? Thank you!

Drawing App with Nodejs, Socket.io and Expressjs

This is my first nodejs app created with express.js 4 and socket.io 1.
Download it on GitHub

A demo is to: drawing.francescopantisano.it

The app permit to draw on a map in real time with other people in a specified “room”, so only who know the name of the room can access.

DrawingAppFirstScreen

You can choose to show/hide the write on the map of the other member, with a “layer system” applied on the canvas.
The canvas is managed with the library jcanvas is very useful.

The room are managed with socket.io, the client connected to are managed by a caching system (node-cache) and a linq library node-linq.

If someone enter on the room after that someone have drawn, the system recover all the written and update the last client connected.

All the drawing action where saved on a buffer to server.

DrawingAppSecondScreen

 

Basic version on github => Download it

Nodemcu Light Control using Nodejs SSDP

LightControl con Nodejs SSDP

questo pacchetto ha una parte di script Arduino da poter lanciare su tutte le vostre NodeMcu e una parte applicativa realizzata con nodejs che gestisce le periferiche ed interagisce con loro utilizzando il protocollo SSDP che trovo veramente interessante per l’aspetto iot, evita di utilizzare/conoscere gli ip delle schede, ogni device connessione in rete espone una propria scheda identificativa, tramite le quale potete riconoscerlo e quindi interagirci:

SSDP.setSchemaURL("description.xml"); 
SSDP.setHTTPPort(80); 
SSDP.setName("NodemcuLightOne"); 
SSDP.setSerialNumber("0001"); 
SSDP.setURL("index.html"); 
SSDP.setModelName("nodemcu"); 
SSDP.setModelNumber("0001"); 
SSDP.setDeviceType("upnp:nodemculight"); 
SSDP.begin();

Il client nodejs è in ascolto sulla porta 3000.
Il device nodemcu viene interrogato sulla porta 80.

##NodeMCU
per configurarlo bisogna prima scaricare i driver https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers e poi, per comodita’, abbiamo utilizzato l’ide di Arduino, debitamente onfigurato così come indicato nelle numerose guide on line. Per installare il mio script su nodemcu ho utilizzato Arduino IDE, se avete bisogno di maggiori informazioni contattatemi pure.

##Node.js
va installato su una macchina e messo in ascolto sulla porta 3000, così come indicato nel pacchetto. 

##INSTALLAZIONE per avviare il server bisogna procedere nel seguente modo:

  1. Scaricare e installare la versione idonea di node ed npm: https://nodejs.org/it/download/
  2. installare il framework express tramite il gestore dei pacchetti: npm intall express

è possibile anche configurare tutto tramite npm install, a patto che il file package.json sia aggiornato nelle dipendenze necessarie. a questo punto si potrà avviare il server:

node app.js

Da notare che su sistemi Debian Node viene avviato con nodejs app.js, in quanto node è un altro applicativo presente sui repository.

 

Come configurare NodeJs SSDP

SSDP la cui definizione è Simple Service Discovery Protocol, viene utilizzato per la ricerca dei device connessi nella rete locale, ho utilizzato la libreria node-ssdp-js semplice da installare e da utilizzare. Bisogna definire una firma nei nostri device da poter successivamente “cercare”.

#JAVASCRIPT NODEJS

var Client = require('node-ssdp-js').Client, client = new Client();

client.on('response', function (response) {
    console.log('Response ssdp device:', response);
    var ipNodeMcuLight = response.referrer.address;
    console.log('IP:', ipNodeMcuLight);
});

client.browse('upnp:nodemculight');

#ARDUINO SCRIPT

SSDP.setDeviceType("upnp:nodemculight");

Progetto “LightControl” di Francesco Pantisano realizzato utilizzando come progetto di base “Plant” di Diomede Mazzone con la collaborazione di Fabio Z Tessitore (@FabioZTessitore) che ringrazio per la pazienza avuta a rispondere alle mie domande.

Tag: NodeJS, ExpressJS, HTML 5, client/server, Simple Service Discovery Protocol (SSDP)

Licenza: GPL 3.0 o successive

Javascript Global Error Handler

Today i’have created a simple class to log in the backend the javascript error, so i can have a real time monitoring of how error appear to the users.

We can use a window.onerror and the addEventListener rewrite.

Window.onerror has been available in most browser, but the argument that are passed on each browser are different:

BrowserMessageURLlineNocolNoerrorObj
Firefox
Chrome
Edge
IE 11
IE 10
IE 9, 8
Safari 10 and up
Safari 9
Android Browser 4.4

This is my class with a _wrap function, and a SendError that trasmit the data on the backend

class ErrorHandler {

	constructor() {
		let $this = this;
		$this._prototypeInit();

		window.onerror = function (message, file, line, col, error) {
			let data = message+" from "+error.stack;
			$this.SendError(data);
		};
	}

	_prototypeInit() {
		let $this = this;
		var addEventListener = window.EventTarget.prototype.addEventListener;
		window.EventTarget.prototype.addEventListener = function (event, callback, bubble) {
			addEventListener.call(this, event, $this._wrap(callback), bubble);
		}
		var removeEventListener = window.EventTarget.prototype.removeEventListener;
		window.EventTarget.prototype.removeEventListener = function (event, callback, bubble) {
			removeEventListener.call(this, event, callback._wrapped || callback, bubble);
		}
	}

	_wrap(func) {
		let $this = this;
		if (!func._wrapped) {
			func._wrapped = function () {
				try {
					func.apply(this, arguments);
				} catch (e) {
					let data = e.message+" from "+e.stack;
					$this.SendError(data);
					throw e;
				}
			}
		}
		return func._wrapped;
	}

	SendError(message) {
		let $this = this;
		fetch('/ErrorHandler/WriteLog', {
			method: 'POST',
			body: JSON.stringify({ message: message }),
			headers: {
				'Content-Type': 'application/json'
			}
		}).then(res => res.json()).catch(error => console.error('Error:', error));
	}
}

In the message we put the stacktrace.
To use it at the init of your application:
let handlerError = new HandlerError();

Write to me if you have some suggestion to improve it.

Angular 6 – ADAL Dynamic Parameter initialization

We have seen in the previous article, how to implement the ADAL Authentication in Angular 6.

Now we can see, how to do, for init the ADAL Module with dynamic parameter, for example we can take them from database, or json file configuration.

We must to open the app.module.ts
Search the “imports” line, where we have write:

@NgModule({
declarations: [
  AppComponent
],
imports: [
  MsAdalAngular6Module.forRoot({
  instance: 'https://adal.resource.com/',
  tenant: '',
  clientId: '',
  redirectUri: window.location.origin,
  navigateToLoginRequestUrl: false,
  cacheLocation: 'localStorage'
}),
RouterModule.forRoot(
 appRoutes,
 { enableTracing: true }
),
 BrowserModule,
],
providers: [
 AuthenticationGuard
]
});

As we can see, the parameter are static, now we want to take them from a web service.

We must to change the “forRoot” function, and pass a function that return the object with parameter configuration

@NgModule({
declarations: [
AppComponent
],
imports: [
    MsAdalAngular6Module.forRoot(function () {
      var request = new XMLHttpRequest();
      request.open('GET', '/api/getParameterADAL', false);
      request.send(null);

      if (request.status === 200) {
        console.log(request.responseText);
        var parameter = JSON.parse(request.responseText);
        return {
          instance: parameter.adfs_instance,
          tenant: parameter.adfs_tenant,
          clientId: parameter.adfs_client_id,
          redirectUri: parameter.adfs_redirect_uri,
          navigateToLoginRequestUrl: false,
          cacheLocation: 'localStorage',
        }
      }
    }()),
RouterModule.forRoot(
appRoutes,
{ enableTracing: true }
),
BrowserModule,
],
providers: [
AuthenticationGuard
]
});

If you have compile error build for example:
Function expressions are not supported in decorators in ‘ɵ0’

Build with:

ng build --optimization=true --outputHashing=a

Enjoy!

Angular 6 – ADAL Authentication

Today i want to talk to you about Microsoft ADAL (Azure Active Directory Authentication Library).
ADAL allows users to authenticate in Active Directory (AD) local or in the cloud and take token to protect the API.

How can i do to integrate it in a Angular 6 app?

1) Install the js library microsoft-adal-angular6

npm i microsoft-adal-angular6

2) Open app.component.ts
2.1) Import the microsoft adal

import { MsAdalAngular6Service } from 'microsoft-adal-angular6';

2.2) In the export class AppComponent change the constructor

export class AppComponent {
title = 'APP Title';
constructor(private adalSvc: MsAdalAngular6Service) {
console.log(this.adalSvc.userInfo);
var token = this.adalSvc.acquireToken('http://adal.resource.com').subscribe((token: string) => {
console.log(token);
});
}
}

3) Open app.module.ts
3.1) Import the microsoft adal

import { MsAdalAngular6Module, AuthenticationGuard } from 'microsoft-adal-angular6';

3.2) We must to change our routes

const appRoutes: Routes = [
{ path: '', component: AppComponent, pathMatch: 'full', canActivate: [AuthenticationGuard] }
];

3.3) In NgModule import library

@NgModule({
declarations: [
AppComponent
],
imports: [
MsAdalAngular6Module.forRoot({
instance: 'https://adal.resource.com/',
tenant: '',
clientId: '',
redirectUri: window.location.origin,
navigateToLoginRequestUrl: false,
cacheLocation: 'localStorage'
}),
RouterModule.forRoot(
appRoutes,
{ enableTracing: true }
),
BrowserModule,
],
providers: [
AuthenticationGuard
]
});

If you want an example Angular 6 ADAL App click here.