python3 ターミナルで日本語が表示されない問題の解決方法

zipcloudという郵便番号から住所を検索できるAPIpython3で利用しているときに、ターミナルで日本語が表示できなかったのでシェアします

元々のコード

 

import urllib.request

url = 'http://zipcloud.ibsnet.co.jp/api/search?zipcode=1000005'

contents = urllib.request.urlopen(url).read()
print(contents)

// ターミナルでの結果
b'{\n\t"message": null,\n\t"results": [\n\t\t{\n\t\t\t"address1": 
"\xe6\x9d\xb1\xe4\xba\xac\xe9\x83\xbd",\n\t\t\t"address2": 
"\xe5\x8d\x83\xe4\xbb\xa3\xe7\x94\xb0\xe5\x8c\xba",\n\t\t\t"address3": 
"\xe4\xb8\xb8\xe3\x81\xae\xe5\x86\x85",\n\t\t\t"kana1": "
\xef\xbe\x84\xef\xbd\xb3\xef\xbd\xb7\xef\xbd\xae\xef\xbd\xb3\xef\xbe\x84"
,\n\t\t\t"kana2": "\xef\xbe\x81\xef\xbe\x96\xef\xbe\x80\xef\xbe\x9e\xef\xbd\xb8",\n\t\t\t"kana3": 
"\xef\xbe\x8f\xef\xbe\x99\xef\xbe\x89\xef\xbd\xb3\xef\xbe\x81",\n\t\t\t"prefcode": 
"13",\n\t\t\t"zipcode": "1000005"\n\t\t}\n\t],\n\t"status": 200\n}'

修正版

デコードしてやることで解決できました!

import urllib.request

url = 'http://zipcloud.ibsnet.co.jp/api/search?zipcode=1000005'

contents = urllib.request.urlopen(url).read()
# ここが追加個所
contents = contents.decode('utf-8')
print(contents)

// 結果
{
        "message": null,
        "results": [
                {
                        "address1": "東京都",
                        "address2": "千代田区",
                        "address3": "丸の内",
                        "kana1": "トウキョウト",
                        "kana2": "チヨダク",
                        "kana3": "マルノウチ",
                        "prefcode": "13",
                        "zipcode": "1000005"
                }
        ],
        "status": 200
}

 

参考記事

Angular htmlで起こる TypeError: Cannot read property ‘name’ of null, undefinedの対処法

Angularのhtmlで変数を呼ぶと時々このようなエラーが起こることがあります

TypeError: Cannot read property 'name' of null
TypeError: Cannot read property 'name' of undefined

 

この問題はnameがnullやundefinedである状態でhtmlがレンダリングされることが問題で、
その結果としてhtmlがクラッシュしてしまいます

しかし「 ?」マークを入れてやることで、nullやundefinedの状態であったとしても
エラーを回避することができます

 

The current hero's name is {{currentHero?.name}}
// -> エラーが起こらない


The null hero's name is {{nullHero.name}}
// エラーが起こる
// エラー内容:  TypeError: Cannot read property 'name' of null in [null].

JavascriptはPromiseやObservableなどを使うことが頻繁にあるので、
サーバーからデータを取得するのを待っていると全体を表示するまでに時間がかかってしまうことが
あります。

そのとき問題になるので、データを取得していないにも関わらず「データを表示する」
という指示を与えていることです
なので「?」マークを使ってエラーを起こさないようにしてあげればデータを取得できたタイミングで
データバインディングで正常に表示できるって訳です

僕自身頻繁に使うのですが、わからないという声もいただいていたので記事にしました〜

参考記事

Template Syntax

 

Angular6 distフォルダ実行方法

本番環境に入れる前にちょっと確認したいと思い、distフォルダで実行してみました

 

// 動かすために必要なのでインストール
$ sudo npm i -g http-server --save

// angularプロジェクトがあるフォルダの一階層上で実行
$  http-server ./dist/<プロジェクト名>/

 

これで実行可能になります!

 

参考記事

How to run the Dist Folder on Local Machine in Angular 6?

Angular http.get() の中でPromiseが使えたかったときの対処法

serviceの中でログインしたか確認した後に、そのユーザーに紐づいている会社情報を取得する
というメソッドの中でPromiseを利用して、会社情報が取得できたら次に行くという
メソッド作成中ハマったのでシェアします

// 修正前
checkAccessToken(): Promise<boolean> {
       const access_token = localStorage.getItem("access_token");
       if (access_token) {
          // ここで return new Promise()  で囲んだがPromiseに入って行かずに実行されない状態が発生
           return this.http.get(`${config.oauth_api}/user_info`, this.getAuthRequestOptions())
               .pipe(map(response => response))
               .pipe(map(response => {
                   this.find_one_with_user_id().then((res: Company) => {
                       this.company = res;
                   });
                   return true;
               })).toPromise();
       }
       return Promise.reject(false);
   }

// 修正後
checkAccessToken(): Promise<boolean> {
       const access_token = localStorage.getItem("access_token");
       if (access_token) {
           // Promiseの追加
           return new Promise((resolve, reject) => {
               this.http.get(`${config.oauth_api}/user_info`, this.getAuthRequestOptions())
                   .pipe(map(response => response))
                     // .pipe(map())ではなく、subscribe()を利用することで中身が発火するようになった
                   .subscribe(response => {
                       this.find_one_with_user_id().then((res: Company) => {
                           this.company = res;
                           resolve(true);
                       }, () => {
                           reject(false);
                       });
                   });
           });
       }
       return Promise.reject(false);
   }


 

時間がないのでなぜ解決することができたかをここで詳しく述べることができないのですが、
この修正を行うことでコードは無事に動きました

なぜ解決することができたかわかる方がいらっしゃいましたら教えていただけると幸いです(__)

 

 

参考記事

 

 

Angular serviceをserviceの中で使う

serviceを異なるserviceで読み込み利用しようとすると動きませんでした

利用するには条件があって、

仮に

  • service1
  • service2

2つのserviceがあったとしたら両方をapp.module.tsに入れると動かず、片方は登録せずにもう片方のserviceimportすれば動くようです

僕は分けることはせず、1つのメソッドを丸々コピペして対処しましたところ、問題なく動きました

参考リンク

 

Injecting a service into another service in Angular

 

 

Angular ファイルダウンロード機能作成方法

アップロード機能はよく作成するのですが、ダウンロードは初めてだったので記事にしました
機能自体は本当に簡単に実装することができるので、コピペでも動きます

// tsファイル
download_file(path: string) {
        (async () => {
            // fetchでアクセス.
            const res = await fetch("http://localhost:5000/" + path);
            // Blob形式でデータ取得.
            const blob =  await res.blob();
            const url = window.URL.createObjectURL(blob);
            let title = "Angular_sample_file";
            
            // aタグを作成して無理やりクリック -> ダウンロード機能発火
            let a = document.createElement('a');
            document.body.appendChild(a);
            a.setAttribute('style', 'display: none');
            a.href = url;
            a.download = title;
            a.click();
            window.URL.revokeObjectURL(url);
        })();
    }
// htmlファイル
<div (click)="download_file('https://wired.jp/wp-content/uploads/2018/01/GettyImages-522585140.jpg')"

※画像はこちらのリンクを利用させていただいております Wired様リンク

 

実際に動かすとダウンロードされ、

このように画像を開くことができます!

 

参考にした記事

 

[フロントエンド] fetchAPIで画像(バイナリーデータ)を取得する

Angular 4 download file from server via http

 

 

sqlalchemy.exc.IntegrityError: (1062, “Duplicate entry ‘1’ for key ‘PRIMARY'”) の解決方法

sqlalchemy.exc.IntegrityError: (pymysql.err.IntegrityError) 
(1062, "Duplicate entry '1' for key 'PRIMARY'")
 [SQL: 'INSERT INTO estimate_request_session (estimate_request_id, is_active, session, expires_in, created_at)
 VALUES (%(estimate_request_id)s, %(is_active)s, %(session)s, %(expires_in)s, %(created_at)s)']
 [parameters: {'estimate_request_id': 630, 'is_active': False, 'session': 'TGUoDiKnICnwm99zqTLDFqDKehhN2Q', 'expires_in': datetime.datetime(2019, 8, 30, 18, 51, 11, 847732), 'created_at': datetime.datetime(2019, 3, 1, 6, 51, 11, 849254)}]

sqlalchemyを利用していて、データを保存しようとしたところ上記エラーが発生。

問題はデータベースで、idauto_incrementになっていないことが原因で発生していたようです

僕はQueriusというMySQLクライアントツールを利用しているので、そちらで変更するとなるとこのような設定になります

問題のテーブルのidを自動で数字を知れレウようにする、auto_increment設定してやれば無事に動きま

 

参考にしたサイト

なし

 

Angular6 Can’t resolve all parameters for : (?, ?, ?, ?, ?, ?, ?, ?).

タイトルの通りの初めて見るエラーが発生しました

Uncaught Error: Can't resolve all parameters for : (?, ?, ?, ?, ?, ?, ?, ?).
 at syntaxError (compiler.js:1021)
    at CompileMetadataResolver.push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata (compiler.js:10922)

 

解決方法

AppModuleのprovidersへimportする際、タイポが原因でエラーが発生していたようです。。。
本当にどうしようもないミスで2時間も使ってしまったので、
同じエラーが下記の「試したこと」でも解決できなければAppModuleのimportあたりを
念の為確認してみてください。。

○ → CompanyFileService
×  → CompanyFile (インターフェースでありserviceではない)

 

試したこと

 

  1. @Injectableが抜けてないかの確認
  2. polyfills.tsのimport ‘core-js/es7/reflect’; が削除されてないかの確認
  3. node_modulesの再インストール
  4. main.tsへimport ‘relfect-metadata’;の追記

参考にした記事

uncaught Error: Can’t resolve all parameters for … #19417

ng build results in Uncaught Error: Can’t resolve all parameters for #10685

Angular CLI 使わず手作業で Angular v5 SPA を webpack でビルドする環境を育てていったときに遭遇したトラブル x 9件の記録
 

 

Angular6 ngDoCheckとngOnChangesの違いについて

今まで基本的にはngOnInitしか使用していなかったのですが、ngDoCheckとngOnChangesに明確な違いがあることを知ったので記事にしておこうと思います

こちらが今回使用するコードです

・header.component.ts

・app.component.ts

の2つです

//header.component.ts

import {Component, DoCheck, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';

@Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit, DoCheck, OnChanges {

    @Input('title') title: number;

    public count = 0;

    constructor() {
    }

    ngOnInit() {
    }

    ngDoCheck() {
    }

    ngOnChanges(changes: SimpleChanges) {
        console.log(changes);
    }
}

//header.component.html
<h2>title => {{title}}</h2>

//app.component.ts
import {Component, OnInit} from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

    public title;

    constructor() {
    }

    ngOnInit() {
    }

}

// app.component.html
<div style="text-align:center">
    <img width="300" alt="Angular Logo"
         src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>


<app-header [title]="title"></app-header>

<input type="text" [(ngModel)]="title">

 

 

 

ngOnChangesについて

 

ngOnChangesはどの変数が変化しても発火するものと考えていましたが、そうではなく@Input要素にのみ発火します

 

 

@Inputの要素ではないcountにsetIntervalでデータを追加してみると

 

// header.component.ts

    @Input('title') title: number;

    public count = 0;

    constructor() {
        setInterval(() => {
            this.count ++;
            console.log(this.count);
        }, 1000);
    }

 

ngOnChangesは発火しません

 

 

ですので、ngOnChangesを使用するときは必ず@Inputの要素であることが重要です

 

ngDoCheckについて

 

ngDoCheckは@Inputの要素ではないが変化を取得したいときに使います

先ほどの例だとcountがそれに当たりますね

ちょいコードを変えます

 

// header.component.ts

 @Input('title') title: number;

    public count = 0;

    constructor() {
        setInterval(() => {
            this.count ++;
        }, 1000);
    }

    ngOnInit() {
    }

    ngDoCheck() {
        console.log(this.count);
    }

    ngOnChanges(changes: SimpleChanges) {
        console.log(changes);
    }

 

こうすることによって以下の画像のように@Input要素でなくともデータを取得することができます。

 

ただしngDoCheckは高負荷になりやすいそうなので注意が必要です

 

参考リンク

If you think `ngDoCheck` means your component is being checked — read this article
Angular2 change detection: ngOnChanges not firing for nested object
Angular 2アンチパターン集

Angular6 エンタークリックイベントの方法

最近忙しくてなかなか更新できませんでしたが。。。

Angular6でエンターを押した後に処理を追加したかったのでそれを実装する方法を探してみました
javascript単体だとコードがちょい長くなってしまいますが、Angularを使うとやはり短くてコンパクトでわかりやすくなりますね

//html
<input (keydown)="onKeydown($event)">

//Typescript
onKeydown(event) {
  if (event.key === "Enter") {
    console.log(event);
  }
}

// その他のキーイベント
<input (keydown.enter)="...">
<input (keydown.a)="...">
<input (keydown.esc)="...">
<input (keydown.shift.esc)="...">
<input (keydown.control)="...">
<input (keydown.alt)="...">
<input (keydown.meta)="...">
<input (keydown.9)="...">
<input (keydown.tab)="...">
<input (keydown.backspace)="...">
<input (keydown.arrowup)="...">
<input (keydown.shift.arrowdown)="...">
<input (keydown.shift.control.z)="...">
<input (keydown.f4)="...">

参考リンク
Angular Quick Tip: Binding Specific Keys to the Keyup and Keydown Events