Developer Blog

Tipps und Tricks für Entwickler und IT-Interessierte

Bash | Cookbook

Configure Bash Environment

Using Bash Completion

Add git completion

Download git-completion.bash to $HOME/etc

$ mkdir $HOME/etc
$ cd $HOME/etc
$ wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash

Add git-prompt to .bashrc

. $HOME/etc/git-completion.sh

Add completion for Makefiles

Add this to .bashrc

complete -W "`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'`" make

Customize Bash prompt

Add git repository/branch to prompt

Download git-prompt.sh to $HOME/etc

$ mkdir -p $HOME/etc
$ cd $HOME/etc
$ wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh

Add git-prompt to .bashrc

. $HOME/etc/git-prompt.sh

Configure prompt to display git branch

export PS1='[\033[33;1m]\w[\033[m] [\033[32m]$(__git_ps1 " 



Writing Bash Scripts

Set vi commands in bash-script

Parsing Parameter

$ brew install gnu-getopt

Bash Script Template

#------------------------------------------------------------------------------------------
CMD_GETOPT=/usr/local/opt/gnu-getopt/bin/getopt

S_OPTS="vdm:"
L_OPTS="verbose,debug,versions,install:,init:"

OPTS=$($CMD_GETOPT --options "$S_OPTS"--longoptions "$L_OPTS"    -- "$@")

eval set $OPTS
shift

while [[ $# -gt 0 ]]; do
    echo "Param 1: '$1'"

    case "$1" in
        -v | --verbose)    VERBOSE=true;                 ;;
        -d | --debug)      DEBUGLEVEL="$2";  shift       ;;

        --versions)        MODE=GETVERSIONS              ;;
        --install)         TYPE="$2";        shift
                           MODE=INSTALL                  ;;

        --init)            MODE=INIT                     ;;

        --)                                  shift; break;;
        * )                                         break;;
    esac

    shift
done

Show progress with a spinner

#!/bin/bash
 
COMMAND="${1^^}"
 
SYMBOL_PASS="$(printf '\e[0;32m\xe2\x9c\x94\e[0m')"
SPINNER_STATE='\|/-'
 
spinner()
{
        local _lastpos=$((${#SPINNER_STATE}-1))
        SPINNER_STATE="${SPINNER_STATE:$_lastpos:1}${SPINNER_STATE:0:$_lastpos}"
 
        printf 
}
 
#---------------------------------------------------------------------------------------------------
#
#---------------------------------------------------------------------------------------------------
if [[ "$COMMAND" = "STEP1" ]]; then
        printf 
        _LASTDATE=
        for _LINE in *.csv
        do
                _FILE="$(basename $_LINE)"
                _CURRDATE=${_FILE:19:8}
                rm    -rf       $_CURRDATE
                mkdir -p        $_CURRDATE
                cp       $_LINE $_CURRDATE
 
                if [[ "$_CURRDATE" = "$_LASTDATE" ]]; then
                        spinner
                else
                        printf "${SYMBOL_PASS}\n${_CURRDATE}: "
                fi
 
                _LASTDATE=$_CURRDATE
        done
        printf "\n"
fi

Github | Einstieg

Github ist eine Webseite, die es ermöglicht, gemeinsam an einem Softwareprojekt zu arbeiten.

Zusätzlich gibt es eine Versionsverwaltung: es wird also jede Änderung mit protokolliert, so das diese überprüft und rückgängig gemacht werden kann.

Einstieg

Der Arbeitsalltag eines Entwicklers, der Github nutzt sieht meistens wie folgt aus

  • er erstellt einmalig ein Github Konto
  • er richtet ein Repository ein, in dem er seine Programme speichert und verwaltet
  • das Repository wird “ausgecheckt“. Dadurch wird eine lokale Kopie auf der Festplatte angelegt
  • er arbeitet und programmiert in dieser lokalen Kopie
  • wenn er mit den Änderungen fertig ist, dann wird das Repository “eingecheckt“. Alle Änderungen sind dann wieder im Repository auf dem GibHub server gespeichert.

Mehr über das Arbeiten mit GibHub kann man hier und hier nachlesen.

Einrichten eines Github-Konto

Schritt 1: notwendige Informationen eingeben

Öffne deinen Browser und geh auf die Seite https://github.com/join

Gibt dann die notwendigen Informationen ein

  • Benutzername
  • Email
  • Passwort

Schritt 2: Verifizieren, das ein Mensch das Konto einrichtet

Klick auf die Pfeile, bis das Bild in der Mitte an der richtigen Stellung steht.

Klick dann auf Done

Schritt 4: Konto einrichten

Klick auf die Schaltfläche Create an account

Schritt 4: Kontotyp einrichten – ein kostenloses Konto

Behalte die Voreinstellung Free bei und klick auf Continue

Schritt 5: Überspringen der letzten Eingaben

Wähle hier aus, was Du selbst angeben möchtest und klick auf Submit.

Oder überspringe diese Schritt und klick auch skip this step

Schritt 6: Bestätigungslink öffnen

Schau in dein Postfach, du solltest eine Email erhalten haben. Klick auf den Bestätigungslink, so das dein Konto eingerichtet wird.

Erstes Repository einrichten

Melde dich bei deinem Github-Konto an, falls Du es noch nicht bist

Schritt 1: Repository erstellen

Auf der Startseite klick auf die Schaltfläche Start a project

Schritt 2. Neues Repository

Schritt 3: Informationen über das Repository

Gib den Namen ein

home

Gib eine Beschreibung ein:

Webseite meines Repositories

Wähle den Typ

Public

Selektiere die Option

Initialize this repository with a README

Klick auf die Schaltfläche

Create repository

Fertig. Das erste Repository ist erstellt!

Arbeiten mit den Repository

Vorbereitung

Als erstes ermitteln wir die URL, um das Repository auszuchecken

Die URL hat immer den gleiche Aufbau und lautet hier:

<a href="https://github.com/ionic-testaccount/home.git">https://github.com/ionic-testaccount/home.git</a>

Der allgemeien Aufbau ist:

<a href="https://github.com/<USERNAME>/<REPONAME>home.git">https://github.com/<USERNAME>/<REPONAME>.git</a>
Auschecken des Repositories

Ausgecheckt wird das Repository mit dem Kommando git clone. Man erstellt einen “Clone” der Repositories auf dem lokalen Rechner. Das Repository wird in einem Ordner erstellt, der den Namen des Repositories erhält:

Änderungen durchführen

Im nächsten Schritt erfolgt das Arbeiten mit dem Repository. Hier werden die gewünschten Änderungen an den Dateien durchgeführt.

Beispielhaft erstellen wir eine neue Datei TODO.md:

Status anzeigen

Mit dem Kommando git status können wir die Änderungen anzeigen lassen. Damit sehen wir, was sich im Vergleich zum Repository auf Github geändert hat.

In unserem Beispiel wird die neue Datei angezeigt als Untracked file:

Änderungen übernehmen

Mit Hilfe der Kommandos git add wird die durchgeführten Änderungen “vorgemerkt” für die Aufnahme in das Repository.

Das eigentliche hinzufügen erfolgt durch das Bestätigen der Änderungen: mit dem Kommando git commit. Durch den Parameter -m wird eine Beschreibung der Änderung hinzugefügt.

Einchecken des Repositories

Zum Abschluss wollen wir die bestätigten Änderungen in das Repository hochladen.

Hier benötigen wir natürlich die erforderlichen Rechte.

Wir erhalten diese, in dem wir unseren Benutzernamen mit angeben. Wir passen dazu die URL des Repositories an:

Jetzt erfolgt das Hochladen mit git push. Es muss nur noch das Passwort angegeben werden:

Der abschliessende Status zeigt, das alle Änderungen übernommen sind und das lokale Repository auf dem gleiche Stand ist, also “clean”

Repository auf Github prüfen

Ein Blick auf die Webseite unseres Repositories zeigt, das die Änderungen übernommen wurde. Wir sehen die neue Datei mit den von uns verwendeten Kommentar.

by Ralph Git und Github

Ionic | Create a simple Calculator

Sources for this tutorial are here.

Preparation

Clone the example

git clone https://github.com/ionic4-toolbox/App-Calculator.git

Starting from new

Before starting, make sure that you are using the current ionic version.If you are new to ionic , then look here for an installation guide.

npm -g install ionic@latest

Create App

ionic start Calculator sidemenu --type angular --no-link --no-git
cd Calculator

Add a new page for our calculator

ionic generate page Calculator

Add new page to sidemenu

Add link to page in app.components.ts file

  public appPages = [
    { title: 'Home', url: '/home', icon: 'home' },
    { title: 'List', url: '/list', icon: 'list' },
    { title: 'Calculator', url: '/calculator', icon: 'grid'
    }
  ];

Add calculation logic to typescript file

4public appPages = [
    { title: 'Home', url: '/home', icon: 'home' },
    { title: 'List', url: '/list', icon: 'list' },
    { title: 'Calculator', url: '/calculator', icon: 'grid' }
];

Add html layout

The layout of our page consists of a header row containing the result and 4 rows containing the buttons of our calculator.

Header
Row 1
Row 2
Row 3

Each row for our keys is build with 5 columns.

Header
Row1, Col1Row1, Col2Row1, Col3Row1, Col4Row1, Col5
Row2, Col1Row2, Col2Row2, Col3Row2, Col4Row2, Col5
Row3, Col1Row3, Col2Row3, Col3Row3, Col4Row3, Col5
Row4, Col1Row4, Col2Row4, Col3Row4, Col4Row4, Col5

Add within the table cells, we place our buttons

Header
789×÷
456+
123x2√x
C0,1/x=

We implement our layout with div’s instead of a html table.

So every row is a

<div class="row">
...
</div>

And within the row we define our buttons also as divs

<div class="number">
   <span (click)="btnClicked('4')">4</span>
   <span (click)="btnClicked('5')">5</span>
   <span (click)="btnClicked('6')">6</span>
</div>
<div class="symbol"><span (click)="btnClicked('+')">+</span></div>
<div class="symbol"><span (click)="btnClicked('-')">-</span></div>

The final html layout looks like this:

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>Rechner</ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
  <div class="calculator">
    <div class="header">
      <div class="window"></div>
      <div class="input"><span>
          <ion-input type="text" placeholder="0" name="display"
                     [(ngModel)]="result">
          </ion-input>
        </span></div>
    </div>
    <div class="keys">
      <div class="row">
        <div class="number">
          <span (click)="btnClicked('7')">7</span>
          <span (click)="btnClicked('8')">8</span>
          <span (click)="btnClicked('9')">9</span>
        </div>
        <div class="symbol"><span (click)="btnClicked('*')">×</span></div>
        <div class="symbol"><span (click)="btnClicked('/')">÷</span></div>
      </div>
      <div class="row">
        <div class="number">
          <span (click)="btnClicked('4')">4</span>
          <span (click)="btnClicked('5')">5</span>
          <span (click)="btnClicked('6')">6</span>
        </div>
        <div class="symbol"><span (click)="btnClicked('+')">+</span></div>
        <div class="symbol"><span (click)="btnClicked('-')">-</span></div>
      </div>
      <div class="row">
        <div class="number">
          <span (click)="btnClicked('1')">1</span>
          <span (click)="btnClicked('2')">2</span>
          <span (click)="btnClicked('3')">3</span>
        </div>
        <div class="symbol">
          <span (click)="btnClicked('square')">x<sup>2</sup></span>
        </div>
        <div class="symbol">
          <span (click)="btnClicked('squareroot')">√x</span>
        </div>
      </div>
      <div class="row">
        <div class="number">
          <span class=dull (click)="btnClicked('C')">C</span>
          <span (click)="btnClicked('0')">0</span>
          <span (click)="btnClicked(',')">,</span>
        </div>
        <div class="symbol">
          <span (click)="btnClicked('reciproc')">1/x</span>
        </div>
        <div class="symbol action">
          <span (click)="btnClicked('=')">=</span>
        </div>
      </div>
    </div>
  </div>
</ion-content>

Add css definitions

html,
body {
    width: 10
    height: 10
    margin: 0;
    padding: 0;
    font-family: "Trebuchet MS", Helvetica, sans-serif;
    font-size: 28px;
}
body {
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #f5f5f5;
}
.calculator {
    margin: 20px;
    widows: 100px;
    border-radius: 10px;
    box-shadow: 0 25px 60px -10px rgba(0, 0, 0, 0.5);
    .header {
        background-color: #000;
        height: 120px;
        border-radius: 10px 10px 0 0;
        .window {
            height: 15px;
            display: flex;
            justify-content: flex-start;
            padding: 10px;
            span {
                width: 10px;
                height: 10px;
                border-radius: 5
                margin-right: 5px;
                cursor: pointer;
                &.red {
                    background-color: #ff5252;
                }
                &.yellow {
                    background-color: #f5a623;
                }
                &.green {
                    background-color: #73c21d;
                }
            }
        }
        .input {
            background-color: #ff0300;
            color: #ffffff;
            padding: 10px 30px;
            font-size: 28px;
            span {
                text-align: right;
                color: #ffffff;
            }
        }
    }
    .keys {
        background: linear-gradient(135deg, #3a3a3a, #000000);
        height: 280px;
        border-radius: 0 0 10px 10px;
        font-size: 24px;
        .row {
            height: 70px;
            display: flex;
            flex-direction: row;
            .number {
                width: 7
                display: flex;
                color: #ffffff;
                span {
                    width: calc(10
                    height: 70px;
                    text-align: center;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    user-select: none;
                    cursor: pointer;
                }
            }
            .symbol {
                width: 2
                background-color: #ffffff;
                font-size: 34px;
                span {
                    width: 10
                    height: 70px;
                    text-align: center;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    user-select: none;
                    cursor: pointer;
                }
                &.action {
                    background: linear-gradient(60deg, #ff0300, #ffa100);
                    border-radius: 0 0 10px 0;
                    color: #ffffff;
                    box-shadow: 0 25px 60px -10px rgba(255, 10, 0, 0.5);
                }
            }
        }
    }
}
.dull {
    font-size: 14px;
    font-weight: bold;
    color: #4a4a4a;
}

Add javascript code for page

import { Component, OnInit } from '@angular/core';
@Component({
	selector: 'app-calculator1',
	templateUrl: './calculator.page.html',
	styleUrls: ['./calculator.page.scss'],
})
export class CalculatorPage implements OnInit {
	result = "";
	constructor() { }
	ngOnInit() {
	}
	btnClicked(btn) {
		console.log('CalculatorPage::btnClicked = ' + btn);
		if (btn == "C") {
			this.result = "";
		} else if (btn == "=") {
			this.result = eval(this.result);
		} else if (btn == "squareroot") {
			this.result = Math.sqrt(eval(this.result)) + "";
		} else if (btn == "square") {
			this.result = eval("(" + this.result + ") * ( " + this.result + ")");
		} else if (btn == "reciproc") {
			this.result = eval(1 + "/ (" + this.result + ")");
		} else {
			this.result += btn;
		}
	}
}

The final result

Installation on Unix

Prepare environment

Install nvm and Node

Change to users home and create users’s profile .bash_profile (if not exist)

cd $HOME
touch .bash_profile

Download nvm install script and run it. The installation script also modifies the users’s profile .bash_profile

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

Run users’s profile, so nvm will be installed. This ist done automatically after login.

. .bash_profile

Install latest Node LTS version

# install latest version
nvm install node --reinstall-packages-from=node

# install a specific version
npm -install 8.12.0

# set nvm aliases (used in direnv configuration)
nvm alias latest 8.12.0
nvm alias default 8.12.0

# install additional packages
npm -g install ionic@latest
npm -g install capacitor@latest

Create Ionic sample Apps

mkdir -p daten
cd daten
ionic start tabs tabs --type angular —-no-link
ionic start sidemen sidemenu --type angular —-no-link

Install direnv

Installation on mac OS. For more  information read here

brew install direnv

Installation on Linux

sudo apt-get update  <br>
sudo apt-get install direnv 

Configfile for direnv

#!/bin/bash

#-------------------------------------------------------------------------------

	SELF=$BASH_ARGV
	HERE="$(cd $(dirname "$SELF"); pwd)"
	SELF="$(basename "$SELF")"

#-------------------------------------------------------------------------------
PRINT()
{
	GRP="$1"; shift
	CMD="$1"; shift
	PAR="$*"

        printf 
}

#-------------------------------------------------------------------------------
	PRINT "config" "$HERE" "$SELF"

	PYTHON_VERSION=2.7.14
	NODE_VERSION=latest

	export NVM_DIR="$HERE/.env/nvm"

	PRINT "setup" "nvm" "$NVM_DIR"
	. /usr/local/opt/nvm/nvm.sh

	PRINT "set latest" "nvm" "$NODE_VERSION"
        nvm use $NODE_VERSION --silent

	PRINT "set latest" "pyenv" "$PYTHON_VERSION"
	pyenv local $PYTHON_VERSION 2>&-

	PRINT "Enabled" "nvm"      "$(nvm      --version)"
	PRINT "Enabled" "node"     "$(node     --version | sed '1,$s/v//g')"
	PRINT "Enabled" "npm"      "$(npm      --version)"
	PRINT "Enabled" "python"   "$(python   --version 2>&1)"
	PRINT "Enabled" "python2"  "$(python2  --version 2>&1)"

.bashrc

# setup direnv
eval "$(direnv hook bash)"

Node.js | Cookbook

Find out location of command

npm -g install which

Working with local repositories

Installieren des Node Modules npm_lazy

npm -g install npm_lazy

Konfigurationsdatei erstellen

npm_lazy --init >npm_lazy.js

npm_lazy starten

npm_lazy --config npm_lazy.js

Node-Umgebungen zur Nutzung des lokaln repositries konfiguieren

npm config set registry http://localhost:8080/

Ionic | App from Scratch – Adding Content

In this blog, we will discus the steps to add additional content (pages, components) to your existing app. We will start with the App From Scratch we create here.

Preparation

Configure Visual Studio Code

First, we will configure Visual Studio Code to show only the desired folders for this tutorial.

We will hide the folders node_modules, e2e and .env

To do this, select Code / Prefecences / Settings

Visual Studio Code will open the settings in a editor window. You will see the default user settings on the left, and the current user settings on the right.

Look for the lines unter “files.exclude” and add or edit the desired content.

Setting to true means exclude (remember the title of the group: files.exclude)

Open required windows

As we add some content, we want to see immediately the results.

So,  i opened three windows

  • Visual Studio Code
  • Browser Windows
  • Console, where we start the ionic server

Change directory structure

Now we can start: Lets add some pages we will use to contain Ionic Components (Buttons, Text, Switches, Lists, Grids, …)

Out app have 3 pages. You will find them in them explorer window

First, i want to change the directory structure.

For each component type, we will add, i want to a a separate folder.

So, first: create a folder pages for our pages

Next, move the pages folders home, list and about into the newly create folder

After that, go into the console, stop the running ionic serve command and restart it to force a new compilation of our app

$ ionic serve
> ng run app:serve --host=0.0.0.0 --port=8100

In the console window, we will see an error

[ng] ERROR in Could not resolve module ./home/home.module relative to .../app_from_scratch/src/app/app-routing.module.ts

This is, because we changes the directory path of the pages. We had to adjust the new path in out app: in app-routing.module.ts

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', loadChildren: './pages/home/home.module#HomePageModule' },
  { path: 'list', loadChildren: './pages/list/list.module#ListPageModule' },
  { path: 'about', loadChildren: './pages/about/about.module#AboutPageModule' }
];

Add page: ActionSheet

Ionic offers a huge amount of amazing components. So, we will demonstrate the use of this components step by step. We will take the inspiration from here.

Starting with Action Sheets.

  • Documentation is here
ionic generate page ActionSheet
> ng generate page ActionSheet
CREATE src/app/action-sheet/action-sheet.module.ts (569 bytes)
CREATE src/app/action-sheet/action-sheet.page.scss (0 bytes)
CREATE src/app/action-sheet/action-sheet.page.html (138 bytes)
CREATE src/app/action-sheet/action-sheet.page.spec.ts (727 bytes)
CREATE src/app/action-sheet/action-sheet.page.ts (279 bytes)
UPDATE src/app/app-routing.module.ts (736 bytes)
[OK] Generated page!

To add the new page to the sidemenu, change the AppPages array in app.component.ts

public appPages = [
  { title: 'Home', url: '/home', icon: 'home' },
  { title: 'List', url: '/list', icon: 'list' },
  { title: 'About', url: '/about', icon: '' },
  { title: 'ActionSheet', url: '/ActionSheet', icon: 'list' }
];

Notice the different spelling of the url (different case of letters). Whatever spelling you choose, it has to fit to the path value in the app-routing.module.ts

Next, move the page to the pages folder and change the path in app-routing.modules.ts

Add the sidemenu button to the actionSheet Page (in action-sheet.page.html)

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>ActionSheet</ion-title>
  </ion-toolbar>
</ion-header>

Ok, well done

Next, add a button and the code for displaying the action sheet. The source is here.

Change your html page: action-sheet.page.html

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>ActionSheet</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding fullscreen>
  <ion-button expand="block" id="basic" (click)="presentBasic()">Basic</ion-button>
  <ion-button expand="block" id="noBackdropDismiss" (click)="presentNoBackdropDismiss()">No Backdrop Dismiss</ion-button>
  <ion-button expand="block" id="alertFromActionSheet" (click)="presentAlert()">Alert from Action Sheet</ion-button>
  <ion-button expand="block" id="scrollableOptions" (click)="presentScroll()">Scrollable Options</ion-button>
  <ion-button expand="block" id="scrollWithoutCancel" (click)="presentScrollNoCancel()">Scroll Without Cancel</ion-button>
  <ion-button expand="block" id="cancelOnly" (click)="presentCancelOnly()">Cancel Only</ion-button>
  <ion-button expand="block" id="icons" (click)="presentIcons()">Icons</ion-button>
  <ion-button expand="block" id="cssClass" (click)="presentWithCssClass()">Custom CSS Class</ion-button>
</ion-content>

Change your Style: action-sheet.page-scss

app-action-sheet {
}

Change the Code: action-sheet.page.ts. Source is here

import { Component, OnInit } from "@angular/core";
import { Platform, ActionSheetController } from "@ionic/angular";

@Component({
  selector: "app-action-sheet",
  templateUrl: "./action-sheet.page.html",
  styleUrls: ["./action-sheet.page.scss"]
})
export class ActionSheetPage implements OnInit {
  constructor(
    public platform: Platform,
    public actionSheetController: ActionSheetController
  ) {}

  ngOnInit() {}


  public changeColor(ev) {

  }

  async presentActionSheet() {
    const actionSheet = await this.actionSheetController.create({
      header: "Albums",
      buttons: [{
        text: 'Delete',
        role: 'destructive',
        icon: 'trash',
        handler: () => {
          console.log('Delete clicked');
        }
      }, {
        text: 'Share',
        icon: 'share',
        handler: () => {
          console.log('Share clicked');
        }
      }, {
        text: 'Play (open modal)',
        icon: 'arrow-dropright-circle',
        handler: () => {
          console.log('Play clicked');
        }
      }, {
        text: 'Favorite',
        icon: 'heart',
        handler: () => {
          console.log('Favorite clicked');
        }
      }, {
        text: 'Cancel',
        icon: 'close',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheet.present();
  }

  async presentBasic() {
    console.log('ActionSheetPage:presentBasic');

    const actionSheet = await this.actionSheetController.create({
      header: "Albums",
      buttons: [{
        text: 'Delete',
        role: 'destructive',
        icon: 'trash',
        handler: () => {
          console.log('Delete clicked');
        }
      }, {
        text: 'Share',
        icon: 'share',
        handler: () => {
          console.log('Share clicked');
        }
      }, {
        text: 'Play (open modal)',
        icon: 'arrow-dropright-circle',
        handler: () => {
          console.log('Play clicked');
        }
      }, {
        text: 'Favorite',
        icon: 'heart',
        handler: () => {
          console.log('Favorite clicked');
        }
      }, {
        text: 'Cancel',
        icon: 'close',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheet.present();
  }
  
  async presentIcons() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      header: "Albums",
      buttons: [{
        text: 'Delete',
        role: 'destructive',
        icon: 'trash',
        handler: () => {
          console.log('Delete clicked');
        }
      }, {
        text: 'Share',
        icon: 'share',
        handler: () => {
          console.log('Share clicked');
        }
      }, {
        text: 'Play (open modal)',
        icon: 'arrow-dropright-circle',
        handler: () => {
          console.log('Play clicked');
        }
      }, {
        text: 'Favorite',
        icon: 'heart',
        role: 'selected',
        handler: () => {
          console.log('Favorite clicked');
        }
      }, {
        text: 'Cancel',
        role: 'cancel',
        icon: 'close',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    })
    await actionSheetElement.present();
  }
  
  async presentNoBackdropDismiss() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      backdropDismiss: false,
      buttons: [{
        text: 'Archive',
        handler: () => {
          console.log('Archive clicked');
        }
      }, {
        text: 'Destructive',
        role: 'destructive',
        handler: () => {
          console.log('Destructive clicked');
        }
      }, {
        text: 'Cancel',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheetElement.present();
  }
  
  async presentAlert() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      buttons: [{
        text: 'Open Alert',
        handler: () => {
          console.log('Open Alert clicked');
        }
      }, {
        text: 'Cancel',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheetElement.present();
  }
  
  async presentScroll() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      buttons: [
        {
          text: 'Add Reaction',
          handler: () => {
            console.log('Add Reaction clicked');
          }
        }, {
          text: 'Copy Text',
          handler: () => {
            console.log('Copy Text clicked');
          }
        }, {
          text: 'Share Text',
          handler: () => {
            console.log('Share Text clicked');
          }
        }, {
          text: 'Copy Link to Message',
          handler: () => {
            console.log('Copy Link to Message clicked');
          }
        }, {
          text: 'Remind Me',
          handler: () => {
            console.log('Remind Me clicked');
          }
        }, {
          text: 'Pin File',
          handler: () => {
            console.log('Pin File clicked');
          }
        }, {
          text: 'Star File',
          handler: () => {
            console.log('Star File clicked');
          }
        }, {
          text: 'Mark Unread',
          handler: () => {
            console.log('Mark Unread clicked');
          }
        }, {
          text: 'Edit Title',
          handler: () => {
            console.log('Edit Title clicked');
          }
        }, {
          text: 'Save Image',
          handler: () => {
            console.log('Save Image clicked');
          }
        }, {
          text: 'Copy Image',
          handler: () => {
            console.log('Copy Image clicked');
          }
        }, {
          text: 'Delete File',
          role: 'destructive',
          handler: () => {
            console.log('Delete File clicked');
          }
        }, {
          text: 'Cancel',
          role: 'cancel', // will always sort to be on the bottom
          handler: () => {
            console.log('Cancel clicked');
          }
        }
      ]
    });
    await actionSheetElement.present();
  }
  
  async presentScrollNoCancel() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      buttons: [
        {
          text: 'Add Reaction',
          handler: () => {
            console.log('Add Reaction clicked');
          }
        }, {
          text: 'Copy Text',
          handler: () => {
            console.log('Copy Text clicked');
          }
        }, {
          text: 'Share Text',
          handler: () => {
            console.log('Share Text clicked');
          }
        }, {
          text: 'Copy Link to Message',
          handler: () => {
            console.log('Copy Link to Message clicked');
          }
        }, {
          text: 'Remind Me',
          handler: () => {
            console.log('Remind Me clicked');
          }
        }, {
          text: 'Pin File',
          handler: () => {
            console.log('Pin File clicked');
          }
        }, {
          text: 'Star File',
          handler: () => {
            console.log('Star File clicked');
          }
        }, {
          text: 'Mark Unread',
          handler: () => {
            console.log('Mark Unread clicked');
          }
        }, {
          text: 'Edit Title',
          handler: () => {
            console.log('Edit Title clicked');
          }
        }, {
          text: 'Save Image',
          handler: () => {
            console.log('Save Image clicked');
          }
        }, {
          text: 'Copy Image',
          handler: () => {
            console.log('Copy Image clicked');
          }
        }, {
          text: 'Delete File',
          role: 'destructive',
          handler: () => {
            console.log('Delete File clicked');
          }
        }
      ]
    });
    await actionSheetElement.present();
  }
  
  async presentCancelOnly() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel', // will always sort to be on the bottom
          handler: () => {
            console.log('Cancel clicked');
          }
        }
      ]
    });
    await actionSheetElement.present();
  }
  
  async presentWithCssClass() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      header: "Custom Css Class",
      cssClass: "my-class my-custom-class",
      buttons: [
        {
          text: 'Test',
          role: 'test',
          cssClass: 'my-cancel-button my-custom-button customClass',
          handler: () => {
            console.log('Cancel clicked');
          }
        }
      ]
    });
    await actionSheetElement.present();
  }
}

Done. Now look at the result

Add page: Buttons

Add page: Toolbar Buttons

Migration

Vorbereitung / Installation

Hier findet ihr die genaue Beschreibung

npm i -D @ionic/v4-migration-tslint
npm i codelyzer

Erstellen einer JSON Datei ionic-migration.json

{
  "rulesDirectory": [
    "@ionic/v4-migration-tslint/rules"
  ],
  "rules": {
    "ion-action-sheet-method-create-parameters-renamed": true,
    "ion-alert-method-create-parameters-renamed": true,
    "ion-datetime-capitalization-changed": true,
    "ion-item-option-method-get-sliding-percent-renamed": true,
    "ion-back-button-not-added-by-default": { "options": [true], "severity": "warning" },
    "ion-button-attributes-renamed": true,
    "ion-button-is-now-an-element": true,
    "ion-chip-markup-has-changed": true,
    "ion-fab-button-is-now-an-element": true,
    "ion-fab-attributes-renamed": true,
    "ion-fab-fixed-content": true,
    "ion-col-attributes-renamed": true,
    "ion-icon-attribute-is-active-removed": true,
    "ion-item-is-now-an-element": true,
    "ion-item-ion-label-required": true,
    "ion-item-attributes-renamed": true,
    "ion-item-divider-ion-label-required": true,
    "ion-item-options-attribute-values-renamed": true,
    "ion-item-option-is-now-an-element": true,
    "ion-label-attributes-renamed": true,
    "ion-list-header-ion-label-required": true,
    "ion-menu-toggle-is-now-an-element": true,
    "ion-navbar-is-now-ion-toolbar": true,
    "ion-option-is-now-ion-select-option": true,
    "ion-radio-attributes-renamed": true,
    "ion-radio-slot-required": true,
    "ion-radio-group-is-now-an-element": true,
    "ion-range-attributes-renamed": true,
    "ion-spinner-attribute-values-renamed": true,
    "ion-tab-attributes-renamed": true,
    "ion-text-is-now-an-element": true,
    "ion-buttons-attributes-renamed": true
  }
}

Migration durchführen

npx tslint -c ionic-migration.json -p tsconfig.json