2016-10-13 9 views
1

Vor ein paar Tagen, ich starrte ASPERN.NET Core und Angular 2. So weit, so gut, außer heute. Eine kleine Einführung in mein Problem.Angular 2 Versprechen liefert immer null ZoneAwarePromise

Ich habe einen wirklich einfachen Web-API-Controller.

[Route("api/[controller]")] 
public class HomeController : Controller 
{  
    private readonly ForumSystemDbContext dbContext; 

    public HomeController(ForumSystemDbContext dbContext) 
    { 
     this.dbContext = dbContext; 
    } 

    [HttpGet] 
    public IActionResult Index() 
    { 
     var posts = this.dbContext.Posts 
      .Include(x => x.PostTag) 
      .ThenInclude(x => x.Tag) 
      .Select(x => new 
      { 
       Title = x.Title, 
       Content = x.Content, 
       Tags = x.PostTag.Select 
       (
        y => new 
        { 
         name = y.Tag.Name 
        } 
       ) 
      }); 

     return this.Json(posts); 
    } 
} 

Ein Winkel Service:

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

export class Post { 
    Content: string; 
    Title: string; 
    Tags: Tag[]; 
} 

export class Tag { 
    Name: string; 
} 

@Injectable() 
export class HomeService { 
    private postsUrl = 'http://localhost:54692/api/home'; 

    constructor(private http: Http) { } 

    getPosts(): Promise<Post[]> { 
     return this.http.get(this.postsUrl) 
         .toPromise() 
         .then(this.extractData) 
         .catch(this.handleError); 
    } 

    private handleError(error: any) { 
     // In a real world app, we might use a remote logging infrastructure 
     // We'd also dig deeper into the error to get a better message 
     let errMsg = (error.message) ? error.message : 
      error.status ? `${error.status} - ${error.statusText}` : 'Server error'; 
     console.error(errMsg); // log to console instead 
     return Promise.reject(errMsg); 
    } 

    private extractData(res: Response) { 
     let body = res.json(); 

     return body.data || {}; 
    } 
} 

Und schließlich home.component.ts

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

import { HomeService } from '../services/home.service'; 

export class Post { 
    Content: string; 
    Title: string; 
    Tags: Tag[]; 
} 

export class Tag { 
    Name: string; 
} 

@Component({ 
    templateUrl: 'app/home/home.html' 
}) 
export class HomeComponent implements OnInit { 
    posts: Post[] = []; 

    constructor(
     private router: Router, 
     private homeService: HomeService) { 
    } 

    ngOnInit(): void { 
     this.homeService.getPosts() 
      .then(posts => this.posts = posts); 
    } 
} 

Das Problem ist, dass Beiträge variable immer eine leere Array ist. Wenn ich

log
this.homeService.getPosts() 

es kehrt

ZoneAwarePromise {__zone_symbol__state: null, __zone_symbol__value: Array[0]} 

ich die offizielle Winkel 2 Dokumentation https://angular.io/docs/ts/latest/guide/server-communication.html#!#promises gelesen haben, aber leider ist es nicht in meinem Fall arbeiten.

Also, ich fragte mich, wo ist mein Fehler?

Ist es eine Art von Konfigurationsproblem oder etwas anderes?

+0

Kurze Frage. Sie verwenden body.data in extractData, aber ich kann .data in Ihrer API nirgendwo sehen. Fehle ich etwas? Wie protokolliert man getPosts()? –

+0

müssen Sie 'rxjs/Rx 'importieren;' –

+0

@ PankajParkar Ich habe es getan, aber das Ergebnis ist das gleiche. – chunk1ty

Antwort

3

Versuchen zu ändern:

private extractData(res: Response) { 
    let body = res.json(); 

    return body.data || {}; 
} 

zu

private extractData(res: Response) { 
    return res.json(); 
} 

Es gibt keine data Eigenschaft in Ihrer Antwort

[{"Title":"title1","Content":"","Tags":[]},{"Title":"title2","Content":"","Tags":[]}] 
+0

Sie haben Recht. Es funktioniert. Danke vielmals. – chunk1ty

0

Versuchen Sie diesen Ansatz für den Service.

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import {Observable} from 'rxjs/Rx'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 

@Injectable() 
export class HomeService { 
    private postsUrl = 'http://localhost:54692/api/home'; 
    constructor(private http:Http) { } 

    getPosts(){ 
    return this.http.get(this.postsUrl).map(
     res => res.json() 
    ); 
    } 

} 

und verbrauchen es von der Komponente wie unten.

getPosts(){ 
    this.homeService.getPosts().subscribe(
     data => { 
     this.posts = data; 
     }, 
     error => { 

     }, 
    () => {} 
    ); 
    } 

Hier this.homeService ist eine Instanz des Service und this.posts ist nur eine lokale Variable, die durch Ihre Beiträge von Web-API zurückgegeben bevölkert wird erhalten.

Home hilft es.

+0

Dieser Ansatz wird auch funktionieren, aber ich bevorzuge mit Versprechen zu arbeiten. Danke trotzdem. – chunk1ty