[TypeScript] リストの中から指定したテキスト複数を表示したい

– localstorageに値を保持して、指定した順番に表示する
– data.splice(0)で配列の値をゼロにする
index.ts

let msg:HTMLParagraphElement
let table:HTMLTableElement

const tweets:string[] = [
	"テキスト1です",
	"テキスト2です",
	"テキスト3です",
	"テキスト4です",
	"テキスト5です"
]

const message = `<h2><a id="title">Tweet</a></h2>
	<p>これは選択したtweetが順番に表示されます</p>`

const data:string[] = []

function doAction(event:any){
	let id = event.target.dataset.id

	const tweet = tweets[id]
	tweet_data.add(tweet)
	tweet_data.save()
	const data = tweet_data.load()
	let disp = ''
	for(let item of data){
		disp += '<h2>'+ item +'</h2>'
	} 
	msg = document.querySelector('#msg')
	msg.innerHTML = disp
}

function doInitial(){
	data.splice(0)
	localStorage.removeItem('tweet_data')
	msg = document.querySelector('#msg')
	msg.innerHTML = message
}

class TweetData {

	add(tweet:string):void {
		data.push(tweet)
	}

	save():void {
		localStorage.setItem('tweet_data', JSON.stringify(data))
	}
	load():string {
		return JSON.parse(localStorage.getItem('tweet_data'))
	}
}

const tweet_data = new TweetData()

function getHtml(tweets:string[]):void {
	table = document.querySelector('#table')
	let html = '<thead><th>Tweet</th><th>Click</th></thead><tbody>'
	let i:number = 0
	for(let item of tweets) {
		html += '<tr><td>' + item + '</td><td><button class="btn btn-primary" id="btn'+i+'" data-id="' + i +'">Click</button></td></tr>'
		i++
	}
	html + '</tbody>'
	table.innerHTML = html
}


window.addEventListener('load', ()=> {
	msg = document.querySelector('#msg')
	msg.innerHTML = message
	getHtml(tweets)
	for(let i=0; i < tweets.length; i++) {
		document.querySelector('#btn'+i).addEventListener('click', doAction)
	}
	document.querySelector('#initial').addEventListener('click', doInitial)
})

[TypeScript] リストの中から指定したテキストを表示したい

index.ts

let msg:HTMLParagraphElement
let table:HTMLTableElement

const tweets:string[] = [
	"テキスト1です",
	"テキスト2です",
	"テキスト3です",
	"テキスト4です",
	"テキスト5です"
]

const message = `<h2><a id="title">This is message</a></h2>
	<p>これはTypeScriptで表示したコンテンツです。</p>`

function getHtml(tweets:string[]):void {
	table = document.querySelector('#table')
	let html = '<thead><th>Tweet</th></thead><tbody>'
	for(let item of tweets) {
		html += '<tr><td>' + item + '</td></tr>'
	}
	html + '</tbody>'
	table.innerHTML = html
}

window.addEventListener('load', ()=> {
	msg = document.querySelector('#msg')
	msg.innerHTML = message
	getHtml(tweets)
})

### クリックしたテキストを表示
index.ts

let msg:HTMLParagraphElement
let table:HTMLTableElement

const tweets:string[] = [
	"テキスト1です",
	"テキスト2です",
	"テキスト3です",
	"テキスト4です",
	"テキスト5です"
]

const message = `<h2><a id="title">Tweet</a></h2>
	<p>これは選択したtweetが表示されます</p>`

function doAction(event:any){
	let id = event.target.dataset.id

	const tweet = tweets[id]
	const disp = '<h2>'+ tweet +'</h2>'

	msg = document.querySelector('#msg')
	msg.innerHTML = disp
}

function getHtml(tweets:string[]):void {
	table = document.querySelector('#table')
	let html = '<thead><th>Tweet</th><th>Click</th></thead><tbody>'
	let i:number = 0
	for(let item of tweets) {
		html += '<tr><td>' + item + '</td><td><button class="btn btn-primary" id="btn'+i+'" data-id="' + i +'">Click</button></td></tr>'
		i++
	}
	html + '</tbody>'
	table.innerHTML = html
}

window.addEventListener('load', ()=> {
	msg = document.querySelector('#msg')
	msg.innerHTML = message
	getHtml(tweets)
	for(let i=0; i < tweets.length; i++) {
		document.querySelector('#btn'+i).addEventListener('click', doAction)
	}
})

クリックしたテキストを表示なら、割と簡単にできる

[TypeScript] TypeORM

$ npm install sqlite3
$ npm install typeorm
$ npm install @nestjs/typeorm

ormconfig.json

{
	"type": "sqlite",
	"database": "data/database.sqlite3",
	"entities": [
		"dist/entities/**/*.entity.js"
	],
	"migrations": [
		"dist/migrations/**/*.js"
	]
}

app.moudle.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

src/entities/mydata.entity.ts

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Mydata {
	@PrimaryGeneratedColumn()
	id: number

	@Column({length: 20})
	name: string

	@Column({length: 100})
	pass: string

	@Column({length: 100, nullable:true})
	mail: string

	@Column()
	age:number
}

### migration
$ npm run build
$ npx typeorm migration:generate -n mydata_migration -d src/migrations
$ npm run build
$ npx typeorm migration:run

$ npx nest generate module mydata
$ npx nest generate service mydata
$ npx nest generate controller mydata

mydata.module.ts

import { Module } from '@nestjs/common';
import { MydataService } from './mydata.service';
import { MydataController } from './mydata.controller';

import { Mydata } from '../entities/mydata.entity' 
import { TypeOrmModule } from '@nestjs/typeorm'

@Module({
  imports: [TypeOrmModule.forFeature([Mydata])],
  providers: [MydataService],
  controllers: [MydataController]
})
export class MydataModule {}

app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MydataModule } from './mydata/mydata.module';

@Module({
  imports: [TypeOrmModule.forRoot(), MydataModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

mydata.service.ts

import { Injectable } from '@nestjs/common';

import { Repository } from 'typeorm'
import { InjectRepository } from '@nestjs/typeorm'
import { Mydata } from '../entities/mydata.entity'

@Injectable()
export class MydataService {
	constructor(
		@InjectRepository(Mydata)
		private readonly mydataRepository: Repository<Mydata>
	) {}

	getAll():Promise<Mydata[]>{
		return this.mydataRepository.find()
	}
}

mydata.controller.ts

import { Controller } from '@nestjs/common';
import { MydataService } from './mydata.service'

@Controller('mydata')
export class MydataController {
	constructor(private readonly mydataService: MydataService){}

	@Get('/')
	root():Promise<any[]>{
		return this.mydataService.getAll()
	}
}

[TypeScript] Nest.js

$ sudo npm install @nestjs/cli -g
$ npx nest new nest_app
> npm
$ npm run start:dev
http://192.168.34.10:3000/
hello worldと表示されている

$ npm install ejs

nest-cli.json

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
  	"assets": ["**/*.ejs"]
  }
}

main.ts

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';
import { join } from 'path'

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  app.useStaticAssets(join(__dirname, '..', 'public'))
  app.setBaseViewsDir(join(__dirname, '..', 'views'))
  app.setViewEngine('ejs')
  
  await app.listen(3000);
}
bootstrap();

views/index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title><%= title %></title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
<body>
  <h1 class="bg-primary text-white p-2"><%= header %></h1>
  <div class="container py-2">
  	<h2 class="mb-3"><%= title %></h2>
  	<div class="alert alert-primary">
  		<%= message %>
  	</div>
  </div>
</body>
</html>

src/app.controller.ts

import { Controller, Get, Render } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  @Render('index')
  root(){
  	return {
  		title: 'Nest sample app',
  		header: 'Nest.js',
  		message: 'Hello world!'
  	}
  }
}

index.ejs

<body>
  <h1 class="bg-primary text-white p-2"><%= title %></h1>
  <div class="container py-2">
  	<h2 class="mb-3"><%= msg %></h2>
  	<div class="alert alert-primary">
  		  <form method="post" action="/">
            <div class="mb-2">
              <label>ID:</label>
              <input type="text" name="id" class="form-control">
            </div>
            <div class="mb-2">
              <label>password:</label>
              <input type="password" name="pass" class="form-control">
            </div>
            <div>
              <input type="submit" value="送信" class="btn btn-info">
            </div>
        </form>
  	</div>
  </div>
</body>

src/app.controller.ts

import { Controller, Get, Post, Body, Render } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('/')
  @Render('index')
  root(){
  	return {
  		title: 'Nest app',
  		msg: 'send form:'
  	}
  }

  @Post('/')
  @Render('index')
  send(@Body() form:any){
  	return {
  		title: 'Nest form',
  		msg: JSON.stringify(form)
  	}
  }
}

### Ajax
app.controller.ts

  @Post('/')
  send(@Body() form:any){
  	return form
  }

index.ejs

  <script src="index.js"></script>
</head>
<body>
  <h1 class="bg-primary text-white p-2"><%= title %></h1>
  <div class="container py-2">
  	<h2 class="mb-3"><%= msg %></h2>
  	<div class="alert alert-primary">
            <div class="mb-2">
              <label>ID:</label>
              <input type="text" name="id" class="form-control">
            </div>
            <div class="mb-2">
              <label>password:</label>
              <input type="password" name="pass" class="form-control">
            </div>
            <div>
              <input type="submit" value="送信" class="btn btn-info">
            </div>
  	</div>
  </div>
</body>

public/index.ts

import { Controller, Get, Post, Body, Render } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('/')
  @Render('index')
  root(){
  	return {
  		title: 'Nest app',
  		msg: 'send form:'
  	}
  }

  @Post('/')
  send(@Body() form:any){
  	return form
  }
}

なんか上手く動いていないような気がするが…

[TypeScript] express

$ sudo npm install -g express-generator
$ npx express -e express_app
$ cd express_app
$ npm install
$ npm run start
http://192.168.34.10:3000/

$ sudo npm install -g express-generator-typescript
$ npx express-generator-typescript express_type_app
$ cd express_type_app
$ npm run start:dev

$ npm install ejs
src/routes/hello.ts

import { Request, Response, Router } from 'express'

const router:Router = Router()

router.get('/', function(req:Request,
		res:Response):void{
	res.render('hello', {
		header:'Hello page',
		title: 'Hello!!',
		msg: 'This is HEllo page!'
	})
})
export default router

src/Server.ts

import helloRouter from './routes/hello'

app.set('view engine', 'ejs')
app.use('/hello', helloRouter)

src/views/hello.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title><%= title %></title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
<body>
  <h1 class="bg-primary text-white p-2"><%= header %></h1>
  <div class="container py-2">
  	<h2 class="mb-3"><%= title %></h2>
  	<div class="alert alert-primary">
  		<%= msg %>
  	</div>
  </div>
</body>
</html>

http://192.168.34.10:3000/hello

なかなか凄いわ

[TypeScript] Vue.js

$ sudo npm install -g @vue/cli
$ npm install –save vue-class-component
$ npx vue create vue3_type_app
Manually select features
◯ TypeScript (スペースキーでセットする)
❯ 3.x
❯ ESLint with error prevention only
❯◉ Lint on save
❯ In dedicated config files

App.vue

<template>
  <HelloWorld />
</template>

HelloWorld.vue

<script lang="tsx">
import { VNode } from 'vue'
import { Vue } from 'vue-class-component'

export default class HelloWorld extends Vue {
  msg = "Vue sample."
  val = 1

  doAction():void {
    this.val += 1
  }

  render():VNode {
    return(<div>
      <h1 class="bg-info text-white p-2">{this.msg}</h1>
      <div class="container">
        <h2 class="my-3">number counter.</h2>
        <div class="alert alert-info">
          <h3 onClick={this.doAction}>{this.val} count.</h3>
        </div>
      </div>
    </div>)
  }

}
</script>

node_modules/vue-class-component/lib”‘ has no exported member ‘Vue’.

うーん、上手くいかんな…

[TypeScript] Reactを使う

$ npx create-react-app react_typescript_app –template typescript
$ cd react_typescript_app
$ npm start

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="manifest" href="%OUBLIC_URL%/manifest.json"/>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
</body>
</html>

App.tsx

import {useState, ReactElement} from 'react';
import './App.css';

function App():ReactElement {
  const [msg, setMsg] = useState("this is sample message.")
  return (
      <div>
        <h1 className="bg-primary text-white p-2">React sample</h1>
        <div className="container">
        <h2 className="my-3">click button!</h2>
        <div className="alert alert-primary">
            <div className="row px-2">
              <h3 id="msg">{msg}</h3>
            </div>
        </div>
        </div>
      </div>
  );
} 


export default App;

### 電卓

import {ChangeEvent, KeyboardEvent, useState, ReactElement} from 'react';
import './App.css';

function App():ReactElement {
  const [val, setVal] = useState(0)
  const [data, setData] = useState<number[]>([])

  const doChange = (event:ChangeEvent):void => {
    const ob = event.target as HTMLInputElement
    const re = Number(ob.value)
    setVal(re)
  }
  const doAction = ():void => {
    const arr:number[] = []
    for(let item of data)
      arr.push(item)
    arr.push(val)
    setData(arr)
    setVal(0)
  }
  const doType = (event:KeyboardEvent):void => {
    if(event.code == 'Enter'){
      doAction()
    }
  }

  let total = 0

  return (
      <div>
        <h1 className="bg-primary text-white p-2">React sample</h1>
        <div className="container">
        <h2 className="my-3">click button!</h2>
        <div className="alert alert-primary">
            <div className="row px-2">
              <input type="number" className="col"
                onChange={doChange} onKeyPress={doType} value={val} />
              <button onClick = {doAction}
                className="btn btn-primary col-2">
                  Click!
              </button>
            </div>
        </div>
        <table className="table">
          <thead><tr><th>value</th><th>total</th></tr></thead>
          <tbody>
          {data.map((v,k)=>{
            total += v
            return <tr key={k}><td>{v}</td><td>{total}</td></tr>
          })}
          </tbody>
        </table>
        </div>
      </div>
  );
} 


export default App;

Reactは比較的わかりやすいか。

[TypeScript] クライアントサイド

html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
	<script src="main.js"></script>
</head>
<body>
	<h1 class="bg-primary text-white p-2">web sample</h1>
	<div class="container">
		<h2 class="my-3">web sample</h2>
		<div class="alert alert-primary">
			<p id="msg">wait...</p>
		</div>
	</div>
</body>
</html>

index.ts

let msg:HTMLParagraphElement

const html = `<h2>This is message</h2>
	<p>これはTypeScriptで表示したコンテンツです。</p>`

window.addEventListener('load', ()=> {
	msg = document.querySelector('#msg')
	msg.innerHTML = html
})
let msg:HTMLParagraphElement

const html = `<h2><a id="title">This is message</a></h2>
	<p>これはTypeScriptで表示したコンテンツです。</p>`

window.addEventListener('load', ()=> {
	msg = document.querySelector('#msg')
	msg.innerHTML = html
	const title:HTMLAnchorElement = document.querySelector('#title')
	title.href = 'http://google.com'
})

Firebaseで開発する

1. Firebaseでプロジェクトを作成
プロジェクト名: typescript-hpscript
google analytics: off

2.Realtime database
create database
location: United States(us-central)
start in test mode

edit rule

{
  "rules": {
    ".read": true,
    ".write": true,
    "boards": {
      ".indexOn":["posted"]
    }
  }
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
	<script src="main.js"></script>
</head>
<body>
	<h1 class="bg-primary text-white p-2">Board</h1>
	<div class="container">
		<h2>send message:</h2>
		<div class="alert alert-primary">
			<div>
				<label>your nickname:</label>
				<input type="text" id="nickname" class="form-control form-control-sm"/>
			</div>
			<div>
				<label>message:</label>
				<input type="text" class="form-control" id="message"/>
			</div>
			<button class="btn btn-primary mt-2" id="btn">
			fetch</button>
			</div>
			<table class="table mb-4" id="table"></table>
			<div class="text-center">
				<button class="btn btn-danger mb-4" id="delete">delete all</button></div>
	</div>
</body>
</html>

index.ts

let nickname: HTMLInputElement
let message:HTMLInputElement
let table:HTMLTableElement
const url = ‘https://typescript-hpscript.firbaseio.com/boards.json’

function doAction(){
const data = {
nickname: nickname.value,
message: message.value,
posted: new Date().getTime()
}
sendData(url, data)
}

function doDelete():void {
fetch(url, {
method: ‘DELETE’
}).then(res=> {
console.log(res.statusText)
getData(url)
})
}

function sendData(url:string, data:object){
fetch(url, {
method: ‘POST’,
mode: ‘cors’,
headers: {
‘Content-Type’:’application/json’
},
body: JSON.stringify(data)
}).then(res=>{
console.log(res.statusText)
getData(url)
})
}

function getData(url:string){
fetch(url).then(res=>res.json()).then(re=> {
let result = `

Message Nickname posted `
let tb = ”
for(let ky in re){
let item = re[ky]
tb = ‘

‘ + item[‘message’] + ‘ ‘
+ item[‘nickname’] + ‘ ‘
+ new Date(item[‘posted’]).toLocaleString()
+ ‘

‘ + tb
}
result += tb + ‘


table.innerHTML = result
})
}

window.addEventListener(‘load’, ()=> {
message = document.querySelector(‘#message’)
nickname = document.querySelector(‘#nickname’)
table = document.querySelector(‘#table’)

const btn : HTMLButtonElement = document.querySelector(‘#btn’)
btn.onclick = doAction
const del :HTMLButtonElement =
document.querySelector(‘#delete’)
del.onclick = doDelete
getData(url)
})
[/code]

ちょっと上手くいかんな

[TypeScript] 重要機能

### 名前空間
– exportで外部から使えるようにする

namespace myapp {
    namespace foundation {
        export interface printable {
            print():void
        }

        export interface stringable {
            getString():string
        }
    }

    export type Person = {
        name:string
        age:number
    }

    export class MyData implements
        foundation.printable,
        foundation.stringable {
            people:Person[] = []

            constructor(){}

            add(nm:string, ag:number){
                this.people.push({name:nm, age:ag})
            }

            print():void {
                console.log('*** mydata ***\n' + this.getString())
            }
            getString():string {
                let res = '[\n'
                for (let item of this.people){
                    res += ' "' +item.name+ ' (' + item.age + ')",\n'
                }
                return res + ']'
            }
        }
}

const mydata = new myapp.MyData()
mydata.add('taro', 39)
mydata.add('hanako', 28)
mydata.add('sachiko', 17)
mydata.add('jiro', 6)
mydata.print()

### モジュールとプログラムの分割
外部公開: export element
読み込み: import (element) from resources

src/lib.ts

export interface printable {
    print():void
}

export interface stringable {
    getString():string
}

export type Person = {
    name:string
    age:number
}

export class MyData implements printable, stringable {
        people:Person[] = []

        constructor(){}

        add(nm:string, ag:number){
            this.people.push({name:nm, age:ag})
        }

        print():void {
            console.log('*** mydata ***\n' + this.getString())
        }
        getString():string {
            let res = '[\n'
            for (let item of this.people){
                res += ' "' +item.name+ ' (' + item.age + ')",\n'
            }
            return res + ']'
        }
    }

index.ts

import { MyData } from './lib'

const mydata = new MyData()
mydata.add('taro', 39)
mydata.add('hanako', 28)
mydata.add('sachiko', 17)
mydata.add('jiro', 6)
mydata.print()

$ npm run build
$ node dist/main.js
*** mydata ***
[
“taro (39)”,
“hanako (28)”,
“sachiko (17)”,
“jiro (6)”,
]

### ミックスイン
複数のクラスを継承して機能を引き継ぐ

function applyMixins(derivedCtor: any, constructors: any[]){
    constructors.forEach((baseCtor) => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
            Object.defineProperty(
                derivedCtor.prototype,
                name,
                Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null)
            );
        });
    });
}

class Person {
    name:string = ''
    title:string = ''

    setPerson(nm:string, tt:string):void {
        this.name = nm
        this.title = tt
    }
}

class Pet {
    kind:string = ''
    age:number = 0

    setPet(k:string, ag:number):void {
        this.kind = k
        this.age = ag
    }
}

class Me {
    print():void {
        console.log(this.name + ' (' + this.age + ')\n'
            + '"' + this.title + '". pet is ' + this.kind + '!')
    }
}

interface Me extends Person, Pet {}
applyMixins(Me, [Person,Pet])

const me = new Me()
me.setPerson('taro', 'designer')
me.setPet('cat', 2)
me.print()

### 非同期処理とasync/await
実行したら後はどれがいつ終わるかわからない

function action(dt:number){
    return new Promise(resolve=>{
        setTimeout(()=> {
            console.log('fished promise!')
            resolve("delay:" + dt)
        }, dt)
    })
}

action(2000).then(res=>console.log(res))
action(1000).then(res=>console.log(res))
action(500).then(res=>console.log(res))

awaitは非同期でも処理が完了するまで待つ

async function doit(){
    let re1 = await action(2000)
    console.log(re1)
    let re2 = await action(1000)
    console.log(re2)
    let re3 = await action(500)
    console.log(re3)
}
doit()

### ネットワークアクセス
fetch().then(response=> hoge) と書く

function getData(url:string){
    fetch(url).then(res=>res.text()).then(re=>{
        console.log(re)
    })
}

const url = 'https://tuyano-dummy-data.firebaseio.com/message.json'
getData(url)

firebaseはCORSを解放しているが、解放していないサイトも多い

function getData(url:string){
    fetch(url).then(res=>res.json()).then(re=>{
        for (let item of re){
            console.log(item)
        }
    })
}

const url = 'https://tuyano-dummy-data.firebaseio.com/sample_data.json'
getData(url)

### ネットワークに同期アクセス
アクセスを非同期化する

async function getData(url:string){
    const response = await fetch(url)
    const result = await response.json()
    for(let item of result){
        console.log(JSON.stringify(item))
    }
}

const url = 'https://tuyano-dummy-data.firebaseio.com/sample_data.json'
getData(url)

### POST送信

async function getData(url:string, obj:object){
    await fetch(url, {
        method: 'POST',
        mode: 'cors',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(obj)
    })
    const response = await fetch(url)
    const result = await response.json()
    console.log(result)
}

const url = "https://tuyano-dummy-data.firebaseio.com/sample_data.json"

const obj = {
    title: 'hello!',
    message: 'This is sample message!'
}

getData(url, obj)

なるほど、TypescriptというよりJavaScriptでも重要なことやな