仮想サーファーの波乗り

仮想化エンジニアの日常

プログラミング・ブロックチェーン・VR/AR・作業効率化・中国事情などに関してよく書きます。

AngularでHTTPアクセスしようとしたら「statusText: Not Found」


Angularのチュートリアルを終えて、HttpClientでAPIアクセスしてレスポンスを画面に表示するように実装しようとすると、APIアクセスができず「statusText: Not Found」というエラーが。

ファイル構成は、ServiceでHTTPアクセスをして、Componentでその処理を受け取るというシンプルなもの。ファイル内容は以下。

currencies.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class CurrenciesService {

  API_URL = 'https://api.coingecko.com/api/v3/coins';
  constructor(private http: HttpClient) {}

  request(perPage: string, pageNum: string): Observable<any> {
    return this.http.get(this.API_URL + '?per_page=' + perPage + '&page=' + pageNum);
  }
}

currencies.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from "@angular/router";

import { CurrenciesService } from "../currencies.service";

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

  perPage = '100';
  pageNum = '1';
  currencies: any[];

  constructor(
    private router: Router,
    private currenciesService: CurrenciesService
  ) {}

  ngOnInit() {
    this.onclick(this.pageNum);
  }

  onclick(pageNum: string) {
    this.currenciesService.request(this.perPage, pageNum)
      .subscribe(response => {
          this.currencies = response;
        }
      );
  }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from "@angular/common/http";
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './/app-routing.module';
import { CurrenciesComponent } from './currencies/currencies.component';
import { CurrenciesService } from "./currencies.service";
import { InMemoryDataService } from "./in-memory-data.service";

@NgModule({
  declarations: [
    AppComponent,
    CurrenciesComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    HttpClientInMemoryWebApiModule.forRoot(InMemoryDataService)
  ],
  providers: [
    CurrenciesService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

in-memory-data.service.ts

import { InMemoryDbService } from 'angular-in-memory-web-api';

export class InMemoryDataService implements InMemoryDbService {
  createDb() {
    const heroes = [
      { id: 11, name: 'Mr. Nice' },
      { id: 12, name: 'Narco' },
      { id: 13, name: 'Bombasto' },
      { id: 14, name: 'Celeritas' },
      { id: 15, name: 'Magneta' },
      { id: 16, name: 'RubberMan' },
      { id: 17, name: 'Dynama' },
      { id: 18, name: 'Dr IQ' },
      { id: 19, name: 'Magma' },
      { id: 20, name: 'Tornado' }
    ];
    return {heroes};
  }
}

この状態でブラウザの開発車ツールを確認すると、以下のようなエラー表示が出ます。

f:id:virtual-surfer:20180603115054p:plain


なんでかなと悩みましたが、「app.module.ts」に記述している「HttpClientInMemoryWebApiModule.forRoot(InMemoryDataService)」が原因でした。この記述をしていることで、Httpの接続先をInMemoryDataServiceにしてしまっているので、「APIにアクセスしようとしてもパスの指定先がないっすよ!」とエラーになっていました。

Angularチュートリアルを終わらせてそのままHTTPアクセスをしようとしたのがミスでした。

app.module.ts

...
HttpClientInMemoryWebApiModule.forRoot(InMemoryDataService) // <- 消す!
...

「app.module.ts」のHttpClientInMemoryWebApiModuleの箇所を消してブラウザを確認すると...

f:id:virtual-surfer:20180603115723p:plain

成功!!

僕はこのエラーに結構悩まされてしまいましたが、チュートリアルを終わらせて、そのままそのアプリケーションで開発していこうとするのは容易に考えられるので、同じようなエラーに出くわした人の参考になれば幸いです。


では。