カテゴリー
Angular

Angular で idb を使うときに発生するasyncIterator プロパティが存在しないエラーの対処方法

Angular で IndexedDB を使いたいと思い、npm の idb を使用していますが、そのまま使うと
以下のエラーが発生します。


ERROR in node_modules/idb/build/esm/entry.d.ts(375,13): error TS2339: Property 'asyncIterator' does not exist on type 'SymbolConstructor'.
node_modules/idb/build/esm/entry.d.ts(375,31): error TS2304: Cannot find name 'AsyncIterableIterator'.
node_modules/idb/build/esm/entry.d.ts(382,98): error TS2304: Cannot find name 'AsyncIterableIterator'.
node_modules/idb/build/esm/entry.d.ts(441,13): error TS2339: Property 'asyncIterator' does not exist on type 'SymbolConstructor'.
node_modules/idb/build/esm/entry.d.ts(441,31): error TS2304: Cannot find name 'AsyncIterableIterator'.
node_modules/idb/build/esm/entry.d.ts(450,109): error TS2304: Cannot find name 'AsyncIterableIterator'.
node_modules/idb/build/esm/entry.d.ts(502,13): error TS2339: Property 'asyncIterator' does not exist on type 'SymbolConstructor'.
node_modules/idb/build/esm/entry.d.ts(502,31): error TS2304: Cannot find name 'AsyncIterableIterator'.
node_modules/idb/build/esm/entry.d.ts(534,13): error TS2339: Property 'asyncIterator' does not exist on type 'SymbolConstructor'.
node_modules/idb/build/esm/entry.d.ts(534,31): error TS2304: Cannot find name 'AsyncIterableIterator'.

使用した NPM モジュール

https://www.npmjs.com/package/idb

対処方法

tsconfig.json の lib に esnext.asynciterable を追加します。


{
  ...
  "compilerOptions": {
    ...
    "lib": [
      ...
      "esnext.asynciterable",
      ...
    ]
  }
}

検証したソースコード


import {openDB, DBSchema} from "idb"

  async openIndexedDB(){

    interface TodoDB extends DBSchema {
      "todo-db": {
        key: string,
        value: {
          workName: string,
          planMinutes: number,
          planSeconds: number,
          isDone: boolean,
        }
      }
    }

    const db = await openDB<TodoDB>('todo-db', 1, {
      upgrade(db) {
        db.createObjectStore('todo-db')
      }
    })

  }

参考にしたサイト

https://github.com/apollographql/graphql-subscriptions/issues/83

カテゴリー
Angular

Angular 7 で global is not defined

Angular 7 で AWS Amplify を使って Cognito と S3 を使ったアプリを開発中に、以下のエラーに遭遇しましたので、対処方法をメモしておきます。


index.js:43 Uncaught ReferenceError: global is not defined
    at Object../node_modules/buffer/index.js (index.js:43)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/aws-sdk/lib/browserHashUtils.js (browserHashUtils.js:1)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/aws-sdk/lib/browserHmac.js (browserHmac.js:1)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/aws-sdk/lib/browserCryptoLib.js (browserCryptoLib.js:1)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/aws-sdk/lib/browser_loader.js (browser_loader.js:4)
    at __webpack_require__ (bootstrap:78)

1. src/polyfills.ts に以下を記述

src/polyfills.ts の末尾に以下を記述します。


(window as any).global = window;

以上。

カテゴリー
Angular TypeScript

Angular 7 で TypeScript エラー TS2580 の対処方法

Angular 7 で開発を進めていると、以下のエラーが発生してコンパイルができなくなりました。


error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try npm i @types/node and then add
node to the types field in your tsconfig.

よくあるエラーで、@types/node がインストールされていないことが原因だと思いましたが、Angular 7 では、src/tsconfig.app.jsonにも設定が必要だったので、メモしておきます。

1. @types/node をインストール

以下のコマンドで、@types/node をインストールします。


npm install --save @types/node

2. tsconfig.json に以下を記述

tsconfig.json ファイルに以下を記述します。


  "compilerOptions": {
    "types": ["node"]
  }

3. src/tsconfig.app.json にも、同じく記述

src/tsconfig.app.json にも同じ記述が必要です。


  "compilerOptions": {
    "types": ["node"]
  }

4. 参考URL

https://stackoverflow.com/questions/53115665/cannot-find-name-require-in-angular-7typescript-3-1-3

カテゴリー
Angular

Angular のコンポーネント組み合わせで、IDEっぽいものを作ってみる

Angular のコンポーネント組み合わせで、IDEっぽいものを作ってみる

Angular には Material Component がたくさん用意されていますので、コピペである程度のGUIを開発していくことができます。

今回は、SideNavMonaco-Editorを使用して、エディターっぽいGUIを開発してみます。

※中身の実装はしていませんので、GUIで動くところだけです。

1. 完成イメージ

右側にVisual Studio Codeライクなエディタを配置し、左側にフォルダツリーを表示します。フォルダツリーはトグルボタンで、表示と非表示を切り替えることができるようにしています。

2. 構成

ものすごくわかりにくいですが、コンポーネント構成はこんな感じです。

Material Design の Drawer と SideNav で大枠を作成し、左側のフォルダツリーは Tree コンポーネントを使用しています。また、右側のエディタは Monaco Editor を使用しました。

3. コンポーネント作成

以下のコマンドで、Angular コンポーネントを作成します。


ng generate component EditorArea

今回は EditorArea というコンポーネントを作成します。

4. Drawer SideNav 配置

https://material.angular.io/components/sidenav/overview

MatSidenavModule が必要ですので、app.module.ts に追加します。

HTML は以下のように書きました。


    <mat-drawer-container class="container" autosize>
    <mat-drawer #drawer class="sidenav" mode="side">
        <p>File Folder Tree</p>
    </mat-drawer>
    <div class="content">
        <p>Editor</p>
    </div>
    </mat-drawer-container>

5. Visual Studio Code ライクエディタ

Monaco Editor というオープンソースのJavascript ライブラリを使用します。

https://github.com/atularen/ngx-monaco-editor

上記の github のページのとおりにパッケージをインストールしていきます。

editor-area.component.ts ファイルに以下を記述します。


  editorOptions = {theme: 'vs-dark', language: 'javascript'};
  code: string= 'function x() {\nconsole.log("Hello world!");\n}';

HTML は以下のようになります。


    <ngx-monaco-editor [options]="editorOptions" [(ngModel)]="code"></ngx-monaco-editor>

6. フォルダツリー

Material Design の Tree コンポーネントを使用します。

https://material.angular.io/components/tree/overview

MatTreeModule が必要ですので、app.module.ts に追加します。

ほぼサンプルのコピーですが、HTML は以下のようにしました。


    <mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
      <!-- This is the tree node template for leaf nodes -->
      <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
        <!-- use a disabled button to provide padding for tree leaf -->
        <button mat-icon-button disabled></button>
        {{node.name}}
      </mat-tree-node>
      <!-- This is the tree node template for expandable nodes -->
      <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
        <button mat-icon-button matTreeNodeToggle
                [attr.aria-label]="'toggle ' + node.name">
          <mat-icon class="mat-icon-rtl-mirror">
            {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
          </mat-icon>
        </button>
        {{node.name}}
      </mat-tree-node>
    </mat-tree>

メニュー構成は以下のように定義します。


    const TREE_DATA: FoodNode[] = [
        {
            name: 'Sample Project',
            children: [
            {name: 'index.js'},
            {name: 'config.json'},
            {name: '.gitignore'},
            ]
        }
    ];

サンプルどおりにその他もろもろをコーディングしていきます。

7. フォルダツリーの表示/非表示のトグルボタン

表示/非表示のトグルは drawer.toggle() 関数で出来ます。

HTML に以下のように書けば実装できると思います。


    <button type="button" mat-button (click)="drawer.toggle();" id="ToggleTreeButton">
    {{ToggleLabel}}
    </button>
カテゴリー
Angular aws TypeScript

TypeScript で AWS DynamoDB のテーブル作成からデータ登録までを行う

1. AWS に登録する

まずは AWS に登録しましょう。無料枠が結構ありますので試しに使ってみるというのもいいと思います。

https://aws.amazon.com/jp/

2. IAM でDynamoDB にアクセスできるユーザーを作成する

IAM は Identity and Access Management の略で、AWS のサービスに接続するためのユーザーやアクセス権限を設定するためのものです。

今回は dynamouser というユーザーを作成します。SDKからのアクセスが必要なので、「プログラムによるアクセス」にチェックを入れます。また、コンソールのアクセスは不要なので、こちらはチェックを外しています。

権限は AmazonDynamoDBFullAccess にしました。実際の運用でフルアクセス権限を付与するのはあまりよくないと思いますが、今回は動作確認ですのでフルアクセス権限のユーザーを作成します。

ユーザーの作成が完了したら、アクセスキーIDとシークレットアクセスキーが表示されます。SDKからの接続時に使用するので、メモしておくか、CSVファイルをダウンロードしておきます。

3. node モジュールの aws-sdk をインストールする

サクッとDynamoDB を使いたいので、Javascript の aws-sdk をインストールします。このコマンドでインストールもサクサク終わります。


npm i aws-sdk

AWS Javascript SDK の公式ドキュメントは以下にあります。

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/

4. DynamoDB にテーブルを作成する


// create_dynamo_db.ts
import * as AWS from "aws-sdk"
AWS.config.update({
    region: "ap-northeast-1",
    accessKeyId: "アクセスキーID",
    secretAccessKey: "シークレットアクセスキー"
})
let dynamodb = new AWS.DynamoDB();
let params : any = {
    TableName: "SampleTable1",
    KeySchema: [
        { AttributeName: "id", KeyType: "HASH" }
    ],
    AttributeDefinitions: [
        { AttributeName: "id", AttributeType: "N" }
    ],
    ProvisionedThroughput: {
        ReadCapacityUnits: 5,
        WriteCapacityUnits: 5
    }
};
dynamodb.createTable(params, (err, data) => {
    if(err) {
        console.log(Unable to create table: ${JSON.stringify(err, undefined, 2)})
    }else {
        console.log(Created table: ${JSON.stringify(data, undefined, 2)})
    }
})
  • AWS.config.update に入力する情報はさきほどIAMでユーザー登録した情報です。このユーザーでDynamoDBにアクセスしていきます。regionは基本的に東京(ap-northeast-1)だと思いますが、違う場所に作成している場合は以下からregisonを調べることができます。

https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html

  • TableName に今回作成するDynamoDB のテーブル名を入力します。
  • KeySchema は、DynamoDBのパーティションキーやソートキーを定義するものです。今回はキー項目はidだけですので、AttributeNameidだけになります。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-keyschema.html

  • AttributeDefinitions は属性定義です。idという項目が数値なのか文字列なのか、などを定義します。N は数値型です。詳しくは以下のページに記載されています。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBMapper.DataTypes.html

AWSのDynamoDBのページを開いて、以下のように表示されていたら成功です。

5. DynamoDB にデータを登録する


import * as AWS from "aws-sdk"
AWS.config.update({
    region: "ap-northeast-1",
    accessKeyId: "アクセスキーID",
    secretAccessKey: "シークレットアクセスキー"
})
var docClient = new AWS.DynamoDB.DocumentClient();
let params : any = {
    TableName: "SampleTable1",
    Item: {
        "id": 1,
        "info": {
            "data": "This is test data",
            "created": "2019-04-08",
            "JP": "これはテストデータです。"
        }
    }
};
docClient.put(params, (err, data) => {
    if(err) {
        console.log(Unable to add item: ${JSON.stringify(err, undefined, 2)})
    }else {
        console.log(PutItem succeeded: ${JSON.stringify(data, undefined, 2)})
    }
})
  • インサートは、DocumentClient.put を使用します。
  • TableName にさきほど作成したテーブル名をセットします。
  • Info は、キー項目である id に紐づいて格納するデータになります。今回は3項目 data, created, JP を格納しています。

AWSのDynamoDBのページを開いて、以下のように表示されていたら成功です。

info の項目をコピーすると、さきほど登録した情報が取得できます。

{ "created" : { "S" : "2019-04-08" }, "data" : { "S" : "This is test data" }, "JP" : { "S" : "これはテストデータです。" }}

カテゴリー
Angular TypeScript

Angular で Monaco Editor を使用する

Monaco Editor とは、Visual Studio Code ライクなエディタをブラウザで使用できるJavascriptライブラリです。

以前、このブログで紹介しました。

https://usefuledge.com/PB_00012_monaco-editor.html

この Monaco Editor を Angular で使えるコンポーネントがありましたので紹介します。

1. ngx-monaco-editor インストール

NPM パッケージをインストールします。


npm install ngx-monaco-editor --save

2. angular.json を編集する。

angular.json の project – プロジェクト名 – architect – build の中、options の assets の中に以下を記述します。


"glob": "**/*", "input": "node_modules/ngx-monaco-editor/assets/monaco", "output": "./assets/monaco/"

こんな感じになると思います。


{
  ... 省略 ...
  "projects": {
    "app1": {
  ... 省略 ...
      "architect": {
        "build": {
          ... 省略 ...
          "options": {
            ... 省略 ...
            "assets": [
              ... 省略 ...
              {
                "glob": "**/*",
                "input": "node_modules/ngx-monaco-editor/assets/monaco", "output": "./assets/monaco/"
              }
            ],
  ... 省略 ...
}

3. app.module.ts に FormsModule と MonacoEditorModule を 追加する。

Import を2つ先頭に記述します。


import { FormsModule } from '@angular/forms';
import { MonacoEditorModule } from 'ngx-monaco-editor';

imports の中に2つ追加します。


@NgModule({
  declarations: [
    ... 省略 ...
  ],
  imports: [
    ... 省略 ...
    FormsModule,
    MonacoEditorModule.forRoot() // use forRoot() in main app module only.
  ],
    ... 省略 ...
})

4. 表示したいコンポーネントの TypeScript ファイルのクラスの中に以下を記述します。


export class AppComponent {
    ... 省略 ...
  editorOptions = {
    theme: 'vs-dark',
    language: 'javascript',
  };
  code: string= 'function x() {\nconsole.log("Hello world!");\n}';
}

5. 表示したいコンポーネントの HTML ファイルのクラスの中に以下を記述します。


<ngx-monaco-editor [options]="editorOptions" [(ngModel)]="code"></ngx-monaco-editor>

6. こんな風に表示されたら成功です。

7. 公式ドキュメントはここにあります。

https://github.com/atularen/ngx-monaco-editor

カテゴリー
Angular TypeScript

Angular で Material Design を使用する

Material Design はGoogleが提唱しているデザインフォーマットです。オープンソースで提供されています。Angular も Google が提唱している SPA フレームワークですので、Angular から簡単に Material Design を使用してみましょう。

1. Angular Material, Angular CDK, Angular Animations をインストールする。

以下のNPMからサクッとインストールします。


npm install --save @angular/material @angular/cdk @angular/animations

2. Material Icon を表示する方法

2.1. app.module.ts を修正して MatIconModule を import する

以下を先頭に追加します。


import {MatIconModule} from '@angular/material/icon';

imports の中に MatIconModule を追加します。


@NgModule({
    ... 省略 ...
  ],
  imports: [
    ... 省略 ...
    MatIconModule
    ... 省略 ...
})

2.2. index.html の中に Material Icon 用のstylesheet を追加します。


<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

2.3. 表示したい箇所にMaterial Icon のHTMLを追加します。


<mat-icon aria-hidden="false" aria-label="Example home icon">home</mat-icon>

こんな風に表示されたら成功です。

3. ボタンを表示する方法

3.1. app.module.ts を修正して MatButtonModule を import する

以下を先頭に追加します。


import {MatButtonModule} from '@angular/material/button';

imports の中に MatButtonModule を追加します。


@NgModule({
    ... 省略 ...
  ],
  imports: [
    ... 省略 ...
    MatButtonModule
    ... 省略 ...
})

3.2. Material Design のテーマCSS をインポートします。

https://material.angular.io/guide/theming

例えばですが、style.css に以下を追加します。


@import '@angular/material/prebuilt-themes/indigo-pink.css';

3.3. 表示したい箇所にMaterial Button のHTMLを追加します。


<button mat-button>Basic</button>
<button mat-button color="primary">Primary</button>
<button mat-button color="accent">Accent</button>
<button mat-button color="warn">Warn</button>
<button mat-button disabled>Disabled</button>

こんな風に表示されたら成功です。

4. ラジオボタンを表示する方法

4.1. app.module.ts を修正して MatButtonModule を import する

以下を先頭に追加します。


import {MatRadioModule} from '@angular/material/radio';

imports の中に MatRadioModule を追加します。


@NgModule({
    ... 省略 ...
  ],
  imports: [
    ... 省略 ...
    MatRadioModule
    ... 省略 ...
})

4.2. 表示したい箇所にMaterial Button のHTMLを追加します。


<mat-radio-group aria-label="Select an option">
  <mat-radio-button value="1">Option 1</mat-radio-button>
  <mat-radio-button value="2">Option 2</mat-radio-button>
</mat-radio-group>

こんな風に表示されたら成功です。

カテゴリー
Angular TypeScript

Angular で SPAの開発を始めよう

Angular はSPAフレームワークの1つです。よくReact や Vue.js と比較されます。Angular の特徴は、Typescriptで記述できることや、パッケージの導入により開発を進められることです。

Angular での開発の始め方

1. Angular CLI のインストールとひな形ソースの作成


npm i -g @angular/cli

でインストールできます。

そのあと、SPAアプリケーションのひな形を生成します。今回は app1 というアプリケーション名でひな形を作成します。


ng new app1

ルーティングを使用するかどうか聞かれますので、 y または N を入力します。


? Would you like to add Angular routing? (y/N) 

使用するスタイルシートフォーマットを選択します。十字キーの上や下で選択し、エンターキーを押します。


? Which stylesheet format would you like to use? (Use arrow keys)
>  CSS
  SCSS   [ http://sass-lang.com/documentation/file.SASS_REFERENCE.html#syntax ]
  Sass   [ http://sass-lang.com/documentation/file.INDENTED_SYNTAX.html       ]
  Less   [ http://lesscss.org                                                 ]
  Stylus [ http://stylus-lang.com                                             ]

app1 フォルダに移動します。


cd app1

テスト用httpサーバーを起動します。


ng serve

正常に処理が終われば、以下のように表示されます。


** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **

Date: 2019-04-02T03:12:16.952Z
Hash: b3a0c7750e80c3ca761e
Time: 25170ms
chunk {es2015-polyfills} es2015-polyfills.js, es2015-polyfills.js.map (es2015-polyfills) 284 kB [initial] [rendered]
chunk {main} main.js, main.js.map (main) 11.5 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 236 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.08 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 16.3 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 3.76 MB [initial] [rendered]
i 「wdm」: Compiled successfully.

http://localhost:4200/にアクセスします。

このように表示されるはずです。

2. コンポーネントの作成方法

Angular ではコンポーネント単位に開発を行います。コンポーネントは独自のHTMLタグで呼び出しができるようになります。

以下の例では、 component1 というコンポーネントを作成します。


ng generate component component1

以下のように表示されるはずです。


CREATE src/app/component1/component1.component.html (29 bytes)
CREATE src/app/component1/component1.component.spec.ts (656 bytes)
CREATE src/app/component1/component1.component.ts (285 bytes)
CREATE src/app/component1/component1.component.css (0 bytes)
UPDATE src/app/app.module.ts (491 bytes)

src/app/component1/component1.component.ts ファイルには以下のように作成されています。


import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-component1',
  templateUrl: './component1.component.html',
  styleUrls: ['./component1.component.css']
})
export class Component1Component implements OnInit {
  constructor() { }
  ngOnInit() {
  }
}

この中の selector がHTMLタグになります。

src/app/app.component.html の末尾に以下を追記します。


<app-component1></app-component1>

component1 works! と表示されていれば、成功です。

以下にチュートリアルがあります。

https://angular.jp/tutorial

Angular Material という、Material UI のAngularコンポーネントが用意されています。

https://material.angular.io/