まっさらなプロジェクトなのにng newでエラーが出た

2019/3/30時点、angular 6.0.3でのお話です。

新しいサービスを作ろうと

angular-cliを心機一転アップデートして

npm uninstall -g @angular/cli
npm cache varify
npm install -g @angular/cli

プロジェクト作って

ng new hogehoge-portal

とりあえず起動!

ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(81,74): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(81,77): error TS1109: Expression expected.

orz

rxjsのバージョンが一定以上上がるとだめみたいなので、

rxjs": "^6.0.0",

rxjs": "6.0.0",

に変えて回避しました。

Goのリポジトリに簡単に移動する方法(Windows)

WindowsにGo言語(ツール含め)をインストールする方法 - 流しのエンジニアひろゆきのブログ

↑以前のブログでインストールしたpeco+ghqですが使い方を忘れてました。

ghqはGoのプロジェクト一覧を出力することができ、pecoはその一覧を↑↓キーで選択することができます。

その2つを組み合わせて以下のようなバッチファイルを作ります。

Windowsコマンドプロンプトでの実行を想定しています。

@echo off

for /f %%i in ('ghq list -p ^| peco') do (
    cd %%i
    break
)

これを例えばpcd.batみたいなファイルに保存し、PATHが通るところに置いて

pcd

と実行すると%GOPATH%/src内のディレクトリが一覧表示され、どれかを選択してEnterキーを押すことで一瞬でディレクトリ移動できます。

design.goファイル分割

公式ドキュメント通りのファイル構成というかdesign.goの書き方にするとdesign.goが肥大化するため、ファイルを分割しました。

大きく3つに分割してます。

  • design
package design // The convention consists of naming the design
// package "design"
import (
    . "github.com/goadesign/goa/design/apidsl"
)

var _ = API("area", func() { // API defines the microservice endpoint and
    Title("area API")                   // other global properties. There should be one
    Description("A simple goa service") // and exactly one API definition appearing in
    Scheme("http")                      // the design.
    Host("localhost:8080")
})
  • resource
package design // The convention consists of naming the design

import (
    . "github.com/goadesign/goa/design" // Use . imports to enable the DSL
    . "github.com/goadesign/goa/design/apidsl"
)

var _ = Resource("point", func() { // Resources group related API endpoints
    BasePath("/points")      // together. They map to REST resources for REST
    DefaultMedia(PointMedia) // services.

    Action("show", func() { // Actions define a single API endpoint together
        Description("Get point by id") // with its path, parameters (both path
        Routing(GET("/:pointId"))      // parameters and querystring values) and payload
        Params(func() {                // (shape of the request body).
            Param("pointId", Integer, "Bottle ID")
        })
        Response(OK, PointMedia) // Responses define the shape and status code
        Response(NotFound)       // of HTTP responses.
    })
    Action("list", func() {
        Description("point list")
        Routing(GET("/"))
        Response(OK, CollectionOf(PointMedia)) // Responses define the shape and status code
        Response(NotFound)                     // of HTTP responses.
    })
})
  • media
package design // The convention consists of naming the design
// package "design"
import (
    . "github.com/goadesign/goa/design" // Use . imports to enable the DSL
    . "github.com/goadesign/goa/design/apidsl"
)

var PointMedia = MediaType("application/vnd.point.area+json", func() {
    Description("A station of mine")
    Attributes(func() { // Attributes define the media type shape.
        Attribute("id", Integer, "Unique station ID")
        Attribute("name", String, "Name of station")
        Required("id", "name")
    })
    View("default", func() { // View defines a rendering of the media type.
        Attribute("id") // Media types may have multiple views and must
        Attribute("name")
    })
})

これでファイルの役割がすっきりして見通しやすくなりました。 goagenはもちろん

goagen bootstrap -d github.com/hryktrd/goaTest/design

で通ります。

完全なサンプルはこちらのリポジトリに置いてあります。

github.com

消費税のコスパ

消費税の増税がいよいよ今月頭に迫ってきました。 そして話題になるのが軽減税率ですね。

生活必需品関連は8%にすると。そして食品もイートインなら10%、テイクアウトなら8%とか実に馬鹿らしい。そこに新聞もまんまと入ろうとしていて何が必需品だと思いましたがそこは主観も入ると思うので置いといて。

軽減税率で国民の負担を下げているようで長期的には自分(国民)の首絞めてるんじゃないかと思います。

なぜか。これは消費税増税を中途半端な8%で止めたことにも関連しますが、こうすることによって上げた税金が無駄に使われてるんです。 まずは8%への増税。3%分丸々税金として他に支出できるならさぞ社会保障や公共事業は潤うだろうと思いますよね。ところがです。この中途半端な増税により例えば100円の商品に110円を払って2円のお釣りになりますよね。財布の中身がどんどんジャラジャラ重くなってきますよね? そう、1円玉が!

そして8%への増税時、この1円玉が緊急で作られたんです。緊急で。それも3000万枚!そしてその製造費用(落札額)1億300万円!3.4円/枚の計算です。

これ8%じゃなくて10%ならかからなかったはずなんですよね。

まずこれが一つの無駄です。3%のうちの何%かは上げた税金のためにかかった経費に消えてしまいます。 キャッシュレス化が進めばそんなに影響なかったのでしょうが今の高齢化社会では致し方ないところでもあります。

次に軽減税率

ぱっと見ただけで以下のようにサイトが作られてます。

もちろんこのサイトづくりもタダではありません。ページ数にもよりますが数百万~高いと数千万したりもします。 そしてこの軽減税率をああだこうだ言いながら作成、運用している人たちの人件費!官僚、政治家の人件費は年間数千万に及びます。そんな人が何人も集まってああだこうだ。人件費だけで年間数億は行くでしょう。これも10%ですぱっと決めて払ってねですませればいりませんでした。

さあこれによって消費税が10%に上がってもどうでもいいところに何割もっていかれるんでしょうか。どれだけが公共事業や社会保障に有効に使われるのでしょうか。

そう考えると軽減税率とか言って少しでも国民の耳障りよく税金を取ろうとすることによってどんどん消費税のコスパが悪くなってきて結局損をするのは納税者ということになります。

あと結構痛いのがレジ。POSシステム。消費税が一部の商品だけ違う税率とかいう仕組みに絶対対応してないと思います。これは改修どころか入れ替えが必要なこともあるかもしれません。これによって各民間企業は何も利益がないところにお金を使わざるを得なくなり、それは商品価格に転嫁せざるを得なくなるでしょう。民間企業は全ての経費を合わせてそれ以上の利益を得ないといけないですからね。

もうこの際ほんとにスパッと消費税全部10%にしてくれないでしょうかね。

goaでAPIを作ってみる

goaを作ってAPIの入り口まで作ってみます。DBまでつないで本格的に作るのは後日。。。

go get -u github.com/goadesign/goa/...
  • 後は自分のプロジェクト内でdesign/design.goを作成し編集します。

変数名などを少し変えたのと、list出力してくれるAPIを追加してます。

package design // The convention consists of naming the design
import (
    . "github.com/goadesign/goa/design" // Use . imports to enable the DSL
    . "github.com/goadesign/goa/design/apidsl"
)

var _ = API("myapi", func() { // API defines the microservice endpoint and
    Title("API to through MyAPI")                    // other global properties. There should be one
    Description("API to through My API without CORS") // and exactly one API definition appearing in
    Scheme("http")                                        // the design.
    Host("localhost:8080")
    // CORSポリシーの定義  ←ここ追加
    Origin("*", func() {
        //クライアントに公開された1つ以上のヘッダー
        Expose("X-Time")
        // 1つまたは複数の許可されたHTTPメソッド
        Methods("GET", "POST", "PUT", "DELETE", "OPTIONS")
        //プリフライト要求応答をキャッシュする時間
        MaxAge(600)
        // Access-Control-Allow-Credentialsヘッダーを設定する
        Credentials()
    })
})

var _ = Resource("station", func() { // Resources group related API endpoints
    BasePath("/stations")      // together. They map to REST resources for REST
    DefaultMedia(StationMedia) // services.

    Action("show", func() { // Actions define a single API endpoint together
        Description("Get station by id") // with its path, parameters (both path
        Routing(
            GET("/:stationID"))
        Params(func() { // (shape of the request body).
            Param("stationID", Integer, "Station ID")
        })
        Response(OK, StationMedia) // Responses define the shape and status code
        Response(NotFound)         // of HTTP responses.
    })
    Action("list", func() { // Actions define a single API endpoint together         // ←ここ丸々追加。リソース一覧取得用
        Description("Get stations") // with its path, parameters (both path
        Routing(
            GET("/")) // parameters and querystring values) and payload
        Response(OK, CollectionOf(StationMedia)) // Responses define the shape and status code    // ←配列を返したい場合CollectionOfを使う
        Response(NotFound)                       // of HTTP responses.
    })
})

// StationMedia defines the media type used to render bottles.
var StationMedia = MediaType("application/vnd.myapi.station+json", func() {
    Description("A station of mine")
    Attributes(func() { // Attributes define the media type shape.
        Attribute("id", Integer, "Unique station ID")
        Attribute("href", String, "API href for making requests on the station")
        Attribute("name", String, "Name of station")
        Required("id", "href", "name")
    })
    View("default", func() { // View defines a rendering of the media type.
        Attribute("id")   // Media types may have multiple views and must
        Attribute("href") // have a "default" view.
        Attribute("name")
    })
})

ここまでできたら

goagen bootstrap  -d github.com\***\***\design

↑自分のプロジェクトディレクトリに合わせてください

上記の例だとstation.goというファイルができるのでその中を編集 // StationController_List: start_implement と書かれている下から追加する感じです。

// List runs the list action.
func (c *StationController) List(ctx *app.ListStationContext) error {
    // StationController_List: start_implement

    res := make(app.MyapiStationCollection, 2)
    st := []app.MyapiStation{{    // ←配列の中身は適当に作成してます。実際はDBから取得してfor分などで代入
        ID:   1,
        Name: "a",
        Href: "b",
    },
        {
            ID:   2,
            Name: "aa",
            Href: "bb",
        }}

    res[0] = &st[0]
    res[1] = &st[1]
    return ctx.OK(res)

    // StationController_List: end_implement
}

// Show runs the show action.
func (c *StationController) Show(ctx *app.ShowStationContext) error {
    // StationController_Show: start_implement

    station := app.MyapiStation{
        ID:   ctx.StationID,
        Name: fmt.Sprintf("Station #%d", ctx.StationID),
        Href: app.StationHref(ctx.StationID),
    }

    return ctx.OK(&station)

    // StationController_Show: end_implement
}

上記でstationオブジェクトの型になっているapp.MyapiStationは design.goで宣言されているMediaTypeの引数に依存してます。

var StationMedia = MediaType("application/vnd.myapi.station+json", func() {

↑のvnd.と+jsonの間です。

  • ここまで来たら
go build -o station.exe

して実行ファイルを作って、できたファイルをそのまま実行しましょう。

http://localhost:8080/stationsにアクセスするとさっき配列に入れた値が表示されると思います。

WindowsにGo言語(ツール含め)をインストールする方法

前提条件

これは2019/3/27時点での実行結果です。 Goのバージョンは1.12.1です。

みんなのGo言語チュートリアルを一通り見た後に本格的な開発に備えて環境を整えていくには最適な感じがしますが、一番最初のGoや周辺ツール(ghqなど)をインストールする手順がMacbrewを想定して書かれているため初めてGo言語の環境を整える人は戸惑うかもしれないので、Windows環境用の手順を作りました。

コマンドで各種バイナリがインストールできるChocolateyを使用します。

Chocolateyのインストール

Goのインストール

  • パッケージインストール
choco install go

を実行し、出てきた質問にはyで答える。 インストールされたGo言語は普通のWindowsアプリと同じくコマンドプロンプトのアプリと機能の中に入っているのでここから管理することも可能です。

GOROOTはC:\go GOPATHは%USERPROFILE%\go Goの実行ファイルは%USERPROFILE%\go\bin

環境変数の設定はスタートメニューでenvと入力すると出てきます。変えたい場合はここで変更してください。

  • ここまで終わったら環境変数を反映させるために一旦コマンドプロンプトを再起動します。  ※以降もChocolatyを使用する場合は管理者モードで開く必要があります。

周辺ツールのインストール

  • peco

    pecoはGoと同じく

choco install peco

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

ghqは残念ながらchocoでインストールできないので、

go get github.com/motemen/ghq

でインストールします。 ※brewは安定版の最新がインストールされるのに対してgo getではgithubでの最新のmasterブランチから取得されるのでその点だけご注意ください。 インストールしたらGoの各リポジトリが置かれる場所を設定しましょう

git config --global ghq.root %GOPATH%\src

以上で基本的なものは入ったと思います。

Google Mapのアイコンの色を変える方法

Google Maps API for Javascriptでマーカーを打つとき、マーカーによって色を変えたいときがあると思います。 アイコン自体を変えたいならicon属性で画像を指定してやればいいのですが、普段なら赤いアイコンを青くしたい場合はどうするんだろうか。。。

ということでいろいろやってみた結果色だけを変えることはできず、かといってこれだけのためにアイコン画像を作るのも嫌だったので、Google Chart APIでアイコン生成して当てはめました。

this.marker[i] = new google.maps.Marker({
                position: markerLatLng,
                icon: data[i]['result'] === 'OK' ? 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E3%83%BB|0000FF|000000' : 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E3%83%BB|FF0000|000000',
                map: this.map
            });

chid=のところを修正するといろいろカスタマイズできます。 文字列|背景色|文字色 として設定します。