Получение массива объектов из службы Angular

Я новичок в Angular (и Javascript, если на то пошло). Я написал службу Angular, которая возвращает массив пользователей. Данные извлекаются из HTTP-запроса, который возвращает данные в формате JSON. При регистрации данных JSON, возвращаемых из HTTP-вызова, я вижу, что этот вызов успешный и верны правильные данные. У меня есть компонент, который вызывает службу, чтобы получить пользователей и HTML-страницу, которая отображает пользователей. Я не могу получить данные от службы к компоненту. Я подозреваю, что неправильно использую Observable. Возможно, я неправильно использую подписку. Если я прокомментирую вызов getUsers в функции ngInit и раскомментирую вызов getUsersMock, все работает отлично, и я вижу данные, отображаемые в списке на странице HTML. Я хотел бы преобразовать данные JSON в массив или список пользователей в службе, а не возвращать JSON из службы и преобразовать компонент.

Данные, возвращаемые из HTTP-вызова, чтобы получить пользователей:

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

user.ts

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

пользовательского 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>
...

!!! ОБНОВЛЕНИЕ!!!

Я читал учебник "герои", но не работал у меня, поэтому я ушел и попробовал другие вещи. Я обновил свой код так, как описывает учебник по героям. Однако, когда я регистрирую значение this.users, он сообщает undefined.

Вот мой пересмотренный user-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);
    }
...

Вот мой пересмотренный 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();
    }
}
...

!!!!!!!!!! ЗАКЛЮЧИТЕЛЬНОЕ РЕШЕНИЕ РАБОТЫ!!!!!!!!!! Это все файлы для окончательного рабочего решения:

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();
    }
}

Ответ 1

Посмотрите на ваш код:

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

и код из https://angular.io/docs/ts/latest/tutorial/toh-pt6.html (Кстати, действительно хороший учебник, вы должны его проверить)

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

HttpService внутри Angular2 уже возвращает наблюдаемое, так что не нужно оборачивать другое наблюдаемое, как вы сделали здесь:

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

Попробуйте следовать руководству по ссылке, которую я предоставил. Вы должны быть в порядке, если вы внимательно изучите это.

---РЕДАКТИРОВАТЬ----

Прежде всего, ГДЕ вы регистрируете переменную this.users? JavaScript не работает таким образом. Ваша переменная не определена, и это нормально, потому что порядок выполнения кода!

Попробуйте сделать это так:

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


    }

Посмотрите, где находится console.log(...)!

Попытайтесь уйти из toPromise(), кажется, это просто для PPL без фона RxJs.

Перейдите по другой ссылке: https://scotch.io/tutorials/angular-2-http-requests-with-observables Снова создайте свой сервис с помощью наблюдаемых RxJs.

Ответ 2

Можете ли вы поделиться вашим рабочим и пересмотренным кодом файлов компонентов, услуг, моделей и HTML файлов для перечисления сведений о пользователе...