2017-01-26 72 views
2

我無法使用我的函數(在服務中)獲取http請求,但如果我直接在我的組件中使用我的函數,它就可以工作。 我使用返回JSON的PHP文件。Angular2 Http獲得服務請求

我收到此錯誤

"Uncaught (in promise): TypeError: Cannot set property stack of [object Object] which has only a getter 
TypeError: Cannot set property stack of [object Object] which has only a getter 
at assignAll (http://localhost:4200/vendor.bundle.js:112997:29) 
at ViewWrappedError.ZoneAwareError (http://localhost:4200/vendor.bundle.js:113068:16) 
at ViewWrappedError.BaseError [as constructor] (http://localhost:4200/vendor.bundle.js:6624:16) 
at ViewWrappedError.WrappedError [as constructor] (http://localhost:4200/vendor.bundle.js:6686:16) 
at new ViewWrappedError (http://localhost:4200/vendor.bundle.js:63377:16) 
at CompiledTemplate.proxyViewClass.DebugAppView._rethrowWithContext (http://localhost:4200/vendor.bundle.js:90236:23) 
at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (http://localhost:4200/vendor.bundle.js:90209:18) 
at ViewRef_.detectChanges (http://localhost:4200/vendor.bundle.js:64323:20) 
at RouterOutlet.activate (http://localhost:4200/vendor.bundle.js:74734:42) 
at ActivateRoutes.placeComponentIntoOutlet (http://localhost:4200/vendor.bundle.js:25777:16) 
at ActivateRoutes.activateRoutes (http://localhost:4200/vendor.bundle.js:25744:26) 
at http://localhost:4200/vendor.bundle.js:25680:58 
at Array.forEach (native) 
at ActivateRoutes.activateChildRoutes (http://localhost:4200/vendor.bundle.js:25680:29) 
at ActivateRoutes.activate (http://localhost:4200/vendor.bundle.js:25654:14)" 

它不工作

組件

import {Component, OnInit} from '@angular/core'; 
import {ActivatedRoute} from '@angular/router'; 
import {Shoe} from './shoe'; 
import {FileService} from './../services/file.service'; 
import {ShoeService} from './../services/shoe.service'; 
import {Observable} from "rxjs"; 

@Component({ 
    selector: 'shoe', 
    templateUrl: 'shoe-detail.component.html', 
    providers: [FileService] 
}) 
export class ShoeDetailComponent implements OnInit { 

constructor(private shoeService: ShoeService) {} 

data : any; 

ngOnInit() { 
     this.data = this.shoeService.getData(); 
    }); 
} 

服務

import { Injectable } from '@angular/core'; 
import { Shoe } from './../shoe/shoe'; 
import {Http, Response} from '@angular/http'; 

@Injectable() 
export class ShoeService { 

constructor (private http: Http) {} 

getData() { 
    return this.http.get('http://.../test.php') 
     .subscribe(data => data.json()); 
    } 
} 

PHP

<?php 
header("Access-Control-Allow-Origin: *"); 
$data = array(
    array('id' => '1','first_name' => 'Cynthia'), 
    array('id' => '2','first_name' => 'Keith'), 
    array('id' => '3','first_name' => 'Robert'), 
    array('id' => '4','first_name' => 'Theresa'), 
    array('id' => '5','first_name' => 'Margaret') 
); 

echo json_encode($data); 
?> 

它的工作原理

import {Component, OnInit} from '@angular/core'; 
import {ActivatedRoute} from '@angular/router'; 
import {Shoe} from './shoe'; 
import {FileService} from './../services/file.service'; 
import {ShoeService} from './../services/shoe.service'; 
import {Http, Response} from '@angular/http'; 

@Component({ 
    selector: 'shoe', 
    templateUrl: 'shoe-detail.component.html', 
    providers: [FileService] 
}) 
export class ShoeDetailComponent implements OnInit { 

constructor(private fileService: FileService, 
      private shoeService: ShoeService, 
      private route: ActivatedRoute, 
      private http: Http) { 
} 

data: any; 

ngOnInit() { 
    this.http.get('http://...test.php') 
      .subscribe(data => this.data = data.json()); 
    }); 
} 
} 
+1

你提供ShoeService? – chrispy

回答

5

在你的組件,你在呼喚它返回一個可觀察的服務,但您分配直接觀測到您的數據,而不是訂閱它的結果。

應該

ngOnInit() { 
    this.shoeService.getData().subscribe(data => this.data = data); 
}); 

而在你的服務,你應該調用地圖,而不是訂閱,所以你返回數據,而不是HttpResult。

getData(): Observable<any> { 
    return this.http.get('http://.../test.php') 
     .map(data => data.json()); 
    } 
} 

請注意,爲了提供更好的類型支持,您應該定義您的方法返回的內容。例如:getData(): Observable<any>如果用定義的接口類型或接口的集合/數組替換any(如果它是集合),則更好。

export interface IUser {id: number; first_name: string} 

服務方法

getData(): Observable<IUser[]> { 
    return this.http.get('http://.../test.php') 
     .Map(data => data.json() as IUser[]); 
    } 
} 
+0

謝謝你!有用 ! ☺ –

1

您應該使用響應對象,如下

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 

import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 
import 'rxjs/add/operator/do'; 
@Injectable() 

export class ShoeService { 
    constructor(private _http: Http) { 
    } 
    getData(): Observable<any[]> { 
     return this._http.get('http://......') 
      .map((response: Response) => <any[]>response.json()) 
      .do(data => console.log("data we got is " + JSON.stringify(data))) 
       .catch(this.handleError); 

    } 
    private handleError(error: Response) { 
      console.log(error); 
      return Observable.throw(error.json().error || 'Internal Server error'); 
    } 
} 

映射到的數據和ngOnInit應儘可能

ngOnInit() : void{ 
     this._taskService.getData() 
        .subscribe(data => this.data = data, 
        error =>this.errorMessage =<any> error) 
    } 

此外,修改數據的輸入您的ShoeDetailComponent作爲

data : any[]