2017-11-16 11 views
0

こんにちは私はHTTPサービスの使用について簡単に質問しています:角4+ベストプラクティスHTTPサービス

私はこれが正しい方法であるかどうかを知りたいと思います。

タスク

export interface Task { 
    Title: string; 
    AssignedTo: User; 
    TaskStatus: string; 
} 

TaskService

import { Injectable } from '@angular/core'; 
import { HttpClient } from '@angular/common/http'; 
import { Observable } from 'rxjs'; 
import 'rxjs/add/operator/map'; 
import { environment } from '../../environments/environment'; 
import { Task } from '../interfaces/task' 

@Injectable() 
export class TaskService { 

    constructor(private http: HttpClient) { } 

    getTask(id: number): Observable<Task> { 
     const serviceUrl: string = environment.apiUrl + 'Tasks/' + id; 
     return this.http.get(serviceUrl) 
      .map((res: Task) => { 
       return res; 
      }); 
    } 
} 

TaskComponent

export class TaskComponent implements OnInit { 
    task: Task; 
    constructor(
     private taskService: TaskService 
    ) { } 
    ngOnInit() { 
     this.route.params.subscribe(params => { 
      this.getTask(<number>params.id); 
     }); 
    } 
    getTask(id: number) { 
     this.taskService.getTask(id).subscribe(
      res => { this.task = res; console.log(this.task) }, 
      err => { console.log(err); } 
     ) 
    } 
} 

テンプレート

<input type="text" class="form-control" id="title" placeholder="Title"[(ngModel)]="task.Title" name="title"> 

それが今行くための方法だ場合、私は私はまだのようなエラーが...よく分からない:「ERRORのTypeError例外を:プロパティ 『タイトル』の未定義の読み取ることができません」私は交換する場合を除き、私のコンポーネント "タスク:タスク"の "タスク:{}" ...インターフェイスを使用する必要はありますか?

答えて

1

あなたは、観察が終了するまで定義されていない何かのTitleプロパティにアクセスしようとしているので、あなたはそのエラーを取得しています。これを防ぐために、あなたはngIfを使用する必要があります。

<input *ngIf="task" type="text" class="form-control" id="title" placeholder="Title"[(ngModel)]="task.Title" name="title"> 

この方法は、あなたの要素は、タスクがtruthyの値になるまでレンダリングしようとしません。

export class TaskComponent implements OnInit { 
    task$: Observable<Task>; 
    constructor(
     private taskService: TaskService 
    ) { } 
    ngOnInit() { 
     this.task$ = this.route.params.switchMap(p => 
          this.taskService.getTask(<number>p.id)); 
    } 
} 

<input *ngIf="task$ | async as task" type="text" class="form-control" id="title" placeholder="Title"[(ngModel)]="task.Title" name="title"> 

:しかし

しかし、ベストプラクティスは、私の意見では、これはあなたのためのサブスクリプションの管理を担当し、onPush変化検出のようなものを容易にし、よりクリーンで読みやすいコードになるよう、常に非同期パイプを使用することですあなたは、観察可能な非同期(async)与えると、それはあなたのために加入すると(つまり、この特定の状況では問題にはならないでしょうが)メモリリークを防ぐためにすべてをクリーンアップします。あなたが見ることができるように、これは、あなたのコードとするとき、なぜに何が起こっているか、それがより明確になり、この変更は、(相対的に)あなたのコードはかなり減少しました。また、変更検出をプッシュに切り替えることもできますが、これは巨大なアプリのパフォーマンス向上です。私は、オブジェクトこうしてインスタンスでしょう

0

task = <Task>{}; 

それが空またはいっぱい、未定義ではないか、となりますこの方法です。あなたのサービスで

私はあなたが(.jsonを忘れてしまったと思う
0

):

import { Injectable } from '@angular/core'; 
import { HttpClient } from '@angular/common/http'; 
import { Observable } from 'rxjs'; 
import 'rxjs/add/operator/map'; 
import { environment } from '../../environments/environment'; 
import { Task } from '../interfaces/task' 

@Injectable() 
export class TaskService { 

    constructor(private http: HttpClient) { } 

    getTask(id: number): Observable<Task> { 
     const serviceUrl: string = environment.apiUrl + 'Tasks/' + id; 
     return this.http.get(serviceUrl) 
      .map((res: Task) => { 
       return res.json(); //<-- here 
      }); 
    } 
} 

これを行わない場合、結果はstatusCodeを、体のような要求(詳細情報とResponseオブジェクトです、 ...)https://developer.mozilla.org/en-US/docs/Web/API/Responseあなたの結果の構造は、アプリケーションで使用futher

については

、それは非常に良いではありません。コードをAPIに結合します。

結果をキャストするためのインターフェイスを用意することをお勧めします。このように、コードに型を持たないようにしてください。このインターフェースはDTOです。

このコードの後に​​、あなたがコントロールするオブジェクトよりも独自のオブジェクトが必要です。

そして、あなたのサービスであなたは、マッパーを持つことができます。

1)インタフェースはJSに蒸散されていません。

@Injectable() 
export class TaskService { 

    constructor(private http: HttpClient) { } 

    getTask(id: number): Observable<Task> { 
     const serviceUrl: string = environment.apiUrl + 'Tasks/' + id; 
     return this.http 
      .get(serviceUrl) 
      .map(res => this.mapper(res.json()); 
    } 

    private mapper(res: TaskDTO): MyOwnTask { 
     return MyOwnTask(res.Title, res.User, res.TaskStatus) 
    } 
} 
+0

HTTPクライアントの振る舞いは、もはや、角度5でJSON()呼び出しのための必要性を全く変えませんでした。 – bryan60

+0

この情報をお寄せいただきありがとうございます。 – mickaelw

0

は、まあ、それは働いていない理由は2つあります。生成されたJavaScriptコードを見ると、インターフェースはまったく使用されません。 (JavaScriptは単純にそれらをサポートしていません)あなたのコードを翻訳した後、タスクプロパティは定義されていません。

2 /)あなたのプロパティは有効なオブジェクトではないため、要素にバインドされていないため、HTTPリクエストが有効な応答で返されてもコンテンツは更新されません。

解決方法は簡単です。空のオブジェクトをタスクプロパティに割り当てるか、インターフェイスを実装するタスククラスを作成し、いくつかの既定値を持つプロパティを含めます。(nullまたは "プロパティタイプ。。コンポーネントを初期化している間にインスタンス化します。

(以下文法的に正しいことが、あなたがメッセージを取得できない場合があります)

interface iTask{ 
    title: string 
} 

class Task implements iTask{ 
    title: "" 
} 

export class TaskComponent implements OnInit { 
    task: Task; 
    constructor(){ 
     this.task = new Task(); 
    } 
} 
+0

項目2のために動作していない唯一の理由は、一度トランスペアレントになったインターフェイスが消えても問題ありません。 JSは気にしません。気にすることは、未定義の参照のプロパティにアクセスしようとしていることです。 – bryan60

関連する問題