2016-10-26 2 views
7

Ich bin neu in Angular (und Javascript für diese Angelegenheit). Ich habe einen Angular-Dienst geschrieben, der eine Reihe von Benutzern zurückgibt. Die Daten werden von einem HTTP-Aufruf abgerufen, der die Daten im JSON-Format zurückgibt. Wenn ich die JSON-Daten protokolliere, die vom HTTP-Aufruf zurückgegeben werden, kann ich sehen, dass dieser Aufruf erfolgreich ist und die richtigen Daten zurückgegeben werden. Ich habe eine Komponente, die den Dienst aufruft, um die Benutzer zu erhalten, und eine HTML-Seite, die die Benutzer anzeigt. Ich kann die Daten vom Dienst nicht zur Komponente abrufen. Ich vermute, dass ich das Observable falsch verwende. Vielleicht verwende ich auch falsch abonnieren. Wenn ich den getUsers-Aufruf in der ngInit-Funktion auskommentiere und den getUsersMock-Aufruf auskommentiere, funktioniert alles einwandfrei und ich sehe die Daten in der Listbox auf der HTML-Seite. Ich möchte die JSON-Daten in ein Array oder eine Liste von Benutzern im Service konvertieren, anstatt JSON aus dem Service zurückzugeben und die Komponente zu konvertieren.Abrufen eines Objektarrays aus einem Angular-Dienst

Daten von HTTP-Aufruf zurück Benutzer zu erhalten:

[ 
    { 
     "firstName": "Jane", 
     "lastName": "Doe" 
    }, 
    { 
     "firstName": "John", 
     "lastName": "Doe" 
    } 
] 

user.ts

export class User { 
    firstName: string; 
    lastName: string; 
} 

benutzer service.ts

... 
@Injectable 
export class UserService { 
    private USERS: User[] = [ 
     { 
      firstName: 'Jane', 
      lastName: 'Doe' 
     }, 
     { 
      firstName: 'John', 
      lastName: 'Doe' 
     } 
    ]; 

    constructor (private http: Http) {} 

    getUsersMock(): User[] { 
     return this.USERS; 
    } 

    getUsers(): Observable<User[]> { 
     return Observable.create(observer => { 
      this.http.get('http://users.org').map(response => response.json(); 
     }) 
    } 
... 

user.component.ts

... 
export class UserComponent implements OnInit { 
    users: User[] = {}; 

    constructor(private userService: UserService) {} 

    ngOnInit(): void { 
     this.getUsers(); 
     //this.getUsersMock(); 
    } 

    getUsers(): void { 
     var userObservable = this.userService.getUsers(); 
     this.userObservable.subscribe(users => { this.users = users }); 
    } 

    getUsersMock(): void { 
     this.users = this.userService.getUsersMock(); 
    } 
} 
... 

user.component.html

... 
<select disabled="disabled" name="Users" size="20"> 
    <option *ngFor="let user of users"> 
     {{user.firstName}}, {{user.lastName}} 
    </option> 
</select> 
... 

!!! AKTUALISIERUNG !!!

Ich hatte das "Helden" -Tutorial gelesen, arbeitete aber nicht für mich, also ging ich los und probierte andere Dinge aus. Ich habe meinen Code wie im Helden-Tutorial beschrieben neu implementiert. Wenn ich jedoch den Wert von this.users protokolliere, meldet er undefined.

Hier ist meine überarbeitete Benutzer-service.ts

... 
@Injectable 
export class UserService { 
    private USERS: User[] = [ 
     { 
      firstName: 'Jane', 
      lastName: 'Doe' 
     }, 
     { 
      firstName: 'John', 
      lastName: 'Doe' 
     } 
    ]; 

    constructor (private http: Http) {} 

    getUsersMock(): User[] { 
     return this.USERS; 
    } 

    getUsers(): Promise<User[]> { 
     return this.http.get('http://users.org') 
      .toPromise() 
      .then(response => response.json().data as User[]) 
      .catch(this.handleError); 
    } 
... 

Hier ist meine überarbeitete user.component.ts

... 
export class UserComponent implements OnInit { 
    users: User[] = {}; 

    constructor(private userService: UserService) {} 

    ngOnInit(): void { 
     this.getUsers(); 
     //this.getUsersMock(); 
    } 

    getUsers(): void { 
     this.userService.getUsers() 
      .then(users => this.users = users); 

     console.log('this.users=' + this.users); // logs undefined 
    } 

    getUsersMock(): void { 
     this.users = this.userService.getUsersMock(); 
    } 
} 
... 

!!!!!!!!!! Endgültige Arbeit Lösung !!!!!!!!!! Dies ist alle Dateien für die endgültige Arbeitslösung:

user.ts

export class User { 
    public firstName: string; 
} 

user.service.ts

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

import 'rxjs/add/operator/catch'; 
import 'rxjs/add/operator/map'; 

import { User } from './user'; 

@Injectable() 
export class UserService { 
    // Returns this JSON data: 
    // [{"firstName":"Jane"},{"firstName":"John"}] 
    private URL = 'http://users.org'; 

    constructor (private http: Http) {} 

    getUsers(): Observable<User[]> { 
     return this.http.get(this.URL) 
      .map((response:Response) => response.json()) 
       .catch((error:any) => Observable.throw(error.json().error || 'Server error')); 
    } 
} 

user.component.ts

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

import { User }  from './user'; 
import { UserService } from './user.service'; 


@Component({ 
    moduleId: module.id, 
    selector: 'users-list', 
    template: ` 
     <select size="5"> 
      <option *ngFor="let user of users">{{user.firstName}}</option> 
     </select> 
    ` 
}) 

export class UserComponent implements OnInit{ 
    users: User[]; 
    title = 'List Users'; 

    constructor(private userService: UserService) {} 

    getUsers(): void { 
     this.userService.getUsers() 
      .subscribe(
       users => { 
        this.users = users; 
        console.log('this.users=' + this.users); 
        console.log('this.users.length=' + this.users.length); 
        console.log('this.users[0].firstName=' + this.users[0].firstName); 
       }, //Bind to view 
          err => { 
         // Log errors if any 
         console.log(err); 
        }) 
    } 

    ngOnInit(): void { 
     this.getUsers(); 
    } 
} 

Antwort

4

Werfen Sie einen Blick auf Ihren Code:

getUsers(): Observable<User[]> { 
     return Observable.create(observer => { 
      this.http.get('http://users.org').map(response => response.json(); 
     }) 
    } 

und Code von https://angular.io/docs/ts/latest/tutorial/toh-pt6.html (BTW.wirklich gutes Tutorial, sollten Sie es heraus) überprüfen

getHeroes(): Promise<Hero[]> { 
    return this.http.get(this.heroesUrl) 
       .toPromise() 
       .then(response => response.json().data as Hero[]) 
       .catch(this.handleError); 
    } 

Die Httpservice innerhalb Angular2 bereits eine beobachtbare zurückgibt, sou brauchen nicht um eine weitere Observable zu wickeln, wie Sie hier tat:

return Observable.create(observer => { 
     this.http.get('http://users.org').map(response => response.json() 

Versuchen Sie, folge dem Leitfaden in meinem Link. Sie sollten gut sein, wenn Sie es sorgfältig studieren.

--- EDIT ----

Zunächst einmal, wo Sie die this.users Variable log? JavaScript funktioniert nicht so. Ihre Variable ist undefiniert und es ist in Ordnung, wegen der Reihenfolge der Codeausführung!

Probieren Sie es wie dies zu tun:

getUsers(): void { 
     this.userService.getUsers() 
      .then(users => { 
       this.users = users 
       console.log('this.users=' + this.users); 
      }); 


    } 

Sehen Sie, wo die console.log (...) ist!

Versuchen Sie, von toPromise() zurückzutreten, es scheint nur für ppl ohne RxJs Hintergrund zu sein.

Fangen Sie einen anderen Link: https://scotch.io/tutorials/angular-2-http-requests-with-observables Erstellen Sie Ihren Dienst noch einmal mit RxJs Observables.

+0

Sie haben Recht mit Ihrem Punkt. Erwägen Sie auch das Hinzufügen eines Arbeitsbeispiels. – Sefa

+0

Sie können das Arbeitsbeispiel in Hero Tutorial verwenden. Es funktioniert gut. https://angular.io/resources/live-examples/toh-6/ts/plnrr.html – jmachnik

+0

Dank jmachnik. Ich habe meine Frage mit zusätzlichen Informationen aktualisiert. Der Grund, warum mein Code so aussah, wie er war, war, dass ich ihn ursprünglich wie im Helden-Tutorial beschrieben implementiert hatte, aber für meinen User [] in der Komponente "undefiniert" wurde, also ging ich los und probierte andere Dinge aus. Der Code sieht jetzt wie das Tutorial des Helden aus, aber ich werde immer noch undefiniert. Irgendwelche Hinweise? –

Verwandte Themen