Observable?--AngularでURL引数を取得する--

2 min読了の目安(約2500字TECH技術記事

背景

Angularに入門中にURL引数取得方法で色々悩んだので備忘録です。
間違えなどあればご指摘いただければ幸いです。

取得方法(結論)

import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { filter, map } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'roulette-web';
  param1: string;
  param2: string;
  navPrm
  constructor(
    private route: ActivatedRoute
  ) {
  }
  ngOnInit() {
    this.route.queryParamMap.pipe(
      filter(n=>Object.keys(n["params"]).length!==0)
      ).subscribe(
        n=>console.log(n["params"])
      )
}
}

下記のURLのアクセスで

http://localhost:4200/?param1=ddddaa

こんな感じでログが出ます

core.js:26900 Angular is running in development mode. Call enableProdMode() to enable production mode.
app.component.ts:23 {param1: "ddddaa"}
client:52 [WDS] Live Reloading enabled.

解説

Router

ActivatedRouteというのを利用しています。
ここでは実際のネットワークルーティングではなく、URLを擬似的に書き換えて画面が移動しているように見せたりすることができるルーティングをサポートするものです。

queryParamMap

パラメータを取得するものなのですが、このモジュールがobservableというものらしく、このへんで悩みました…

observable

これは私の認識上、「通知する側と通知される側を分ける方法の一つ」という認識です…
プログラムの特性上対象をはっきりさせると依存性が上がり、プログラムの汎用性?やら色々と落ちます。
それを同じ方法で分離する事により、プログラムを簡単に分離して、色々と編集を楽にすることが目的という感じ…

俺の心の中のイメージは上のような図です。
「呼び出し元」と「呼び出し先(Subscribe)」の間にObservableが仲介してくれる感じです。
こうすると「呼び出し元」と「呼び出し先」の依存関係が消えて、関数や呼び出し元の再利用が容易になります。

Subscribe

これは呼び出し先関数と考えて貰えばいいと思っています。
公式サイトを見るとAngularでは下記の3種類がで利用できるようです。

// Create observer object
const myObserver = {
  next: x => console.log('Observer got a next value: ' + x),
  error: err => console.error('Observer got an error: ' + err),
  complete: () => console.log('Observer got a complete notification'),
};

参考:https://angular.jp/guide/observables
nextは呼び出し時、errorはエラー時、completeは終了時って感じですね。

呼び出し元

色々と利用できると公式ドキュメントには記載されていますね。

  • promiseでHTTP Request
  • カウンター
  • HTML DOMからのイベント
  • AJAXでHTTP Request
    などなどで利用できる様子です
    参考:https://angular.jp/guide/rx-library

Operator

Operatorは私のイメージでは流れの中に処理を挟み込めるってイメージです。

こんな感じですね。
よく利用するのはmapやfilterでしょう。

map:取得した通知に対して何らかの処理を行って渡す。
filter:特定の条件に合っていれば通知する。

あと、Operatorを挟む場合はpipeという関数でつなげましょう。
今回利用しているのはfilterでこんな感じでparamsが存在しない場合は通知しないようにしています。

    this.route.queryParamMap.pipe(
      filter(n=>Object.keys(n["params"]).length!==0)
      ).subscribe(
        n=>console.log(n["params"])
      )