从 Angular 服务获取对象数组 [英] Getting an object array from an Angular service

查看:23
本文介绍了从 Angular 服务获取对象数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Angular(以及 Javascript)的新手.我编写了一个返回用户数组的 Angular 服务.数据是从 HTTP 调用中检索的,该调用以 JSON 格式返回数据.在记录 HTTP 调用返回的 JSON 数据时,可以看到该调用成功并返回了正确的数据.我有一个调用服务来获取用户的组件和一个显示用户的 HTML 页面.我无法从服务获取数据到组件.我怀疑我错误地使用了 Observable.也许我也错误地使用了 subscribe .如果我在 ngInit 函数中注释掉 getUsers 调用并取消对 getUsersMock 调用的注释,一切正常,我会看到 HTML 页面的列表框中显示的数据.我想将 JSON 数据转换为服务中的用户数组或列表,而不是从服务返回 JSON 并让组件对其进行转换.

从 HTTP 调用返回的数据以获取用户:

<预><代码>[{"firstName": "简",姓氏":母鹿"},{"firstName": "约翰",姓氏":母鹿"}]

user.ts

导出类用户{名字:字符串;姓氏:字符串;}

用户服务.ts

<代码>...@Injectable导出类 UserService {私人用户:用户[] = [{firstName: '简',姓氏:'母鹿'},{firstName: '约翰',姓氏:'母鹿'}];构造函数(私有 http: Http){}getUsersMock(): 用户[] {返回 this.USERS;}getUsers(): Observable{返回 Observable.create(观察者 => {this.http.get('http://users.org').map(response => response.json();})}...

user.component.ts

<代码>...导出类 UserComponent 实现 OnInit {用户:用户[] = {};构造函数(私有用户服务:用户服务){}ngOnInit(): 无效 {this.getUsers();//this.getUsersMock();}getUsers(): 无效 {var userObservable = this.userService.getUsers();this.userObservable.subscribe(users => { this.users = users });}getUsersMock(): 无效 {this.users = this.userService.getUsersMock();}}...

user.component.html

<代码>...<select disabled="disabled" name="Users" size="20"><option *ngFor="让用户的用户">{{user.firstName}},{{user.lastName}}</选项></选择>...

!!!更新!!!

我一直在阅读英雄"教程,但对我不起作用,所以我去尝试了其他东西.我已经按照英雄教程描述的方式重新实现了我的代码.但是,当我记录 this.users 的值时,它报告 undefined.

这是我修改后的 user-service.ts

<代码>...@Injectable导出类 UserService {私人用户:用户[] = [{firstName: '简',姓氏:'母鹿'},{firstName: '约翰',姓氏:'母鹿'}];构造函数(私有 http: Http){}getUsersMock(): 用户[] {返回 this.USERS;}getUsers(): Promise{返回 this.http.get('http://users.org').承诺().then(response => response.json().data as User[]).catch(this.handleError);}...

这是我修改后的 user.component.ts

<代码>...导出类 UserComponent 实现 OnInit {用户:用户[] = {};构造函数(私有用户服务:用户服务){}ngOnInit(): 无效 {this.getUsers();//this.getUsersMock();}getUsers(): 无效 {this.userService.getUsers().then(users => this.users = users);console.log('this.users=' + this.users);//未定义的日志}getUsersMock(): 无效 {this.users = this.userService.getUsersMock();}}...

!!!!!!!!!!!!最终的工作解决方案 !!!!!!!!!!!!这是最终工作解决方案的所有文件:

user.ts

导出类用户{公共名字:字符串;}

user.service.ts

import { Injectable } from '@angular/core';从@angular/http"导入 { Http, Response };从 'rxjs/Observable' 导入 { Observable };导入 'rxjs/add/operator/catch';导入 'rxjs/add/operator/map';从'./user'导入{用户};@Injectable()导出类 UserService {//返回此 JSON 数据://[{"firstName":"Jane"},{"firstName":"John"}]私人网址 = 'http://users.org';构造函数(私有 http: Http){}getUsers(): Observable{返回 this.http.get(this.URL).map((response:Response) => response.json()).catch((error:any) => Observable.throw(error.json().error || '服务器错误'));}}

user.component.ts

import { Component, OnInit } from '@angular/core';从@angular/router"导入{路由器};从'./user'导入{用户};从 './user.service' 导入 { UserService };@成分({模块 ID:module.id,选择器:'用户列表',模板:`<选择尺寸=5"><option *ngFor="let user of users">{{user.firstName}}</option></选择>`})导出类 UserComponent 实现 OnInit{用户:用户[];title = '列出用户';构造函数(私有用户服务:用户服务){}getUsers(): 无效 {this.userService.getUsers().订阅(用户 =>{this.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);},//绑定查看错误 =>{//记录错误(如果有)控制台日志(错误);})}ngOnInit(): 无效 {this.getUsers();}}

解决方案

看看你的代码:

 getUsers(): Observable{返回 Observable.create(观察者 => {this.http.get('http://users.org').map(response => response.json();})}

和来自 https://angular.io/docs/ts 的代码/latest/tutorial/toh-pt6.html(顺便说一句.非常好的教程,你应该看看)

 getHeroes(): Promise{返回 this.http.get(this.heroesUrl).承诺().then(response => response.json().data as Hero[]).catch(this.handleError);}

Angular2 中的 HttpService 已经返回了一个 observable,所以你不需要像你在这里做的那样包装另一个 Observable:

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

尝试按照我提供的链接中的指南进行操作.仔细研究应该没问题.

---编辑----

首先你在哪里记录 this.users 变量?JavaScript 不是这样工作的.由于代码执行顺序,您的变量未定义,这很好!

尝试这样做:

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

查看 console.log(...) 在哪里!

尝试从 toPromise() 辞职,这似乎只适用于没有 RxJs 背景的人.

获取另一个链接:https://scotch.io/tutorials/angular-2-http-requests-with-observables 使用 RxJs observables 再次构建您的服务.

I am new to Angular (and Javascript for that matter). I've written an Angular service which returns an array of users. The data is retrieved from an HTTP call which returns the data in JSON format. When logging the JSON data returned from the HTTP call, I can see that this call is successful and the correct data is returned. I have a component which calls the service to get the users and an HTML page which displays the users. I cannot get the data from the service to the component. I suspect I am using the Observable incorrectly. Maybe I'm using subscribe incorrectly as well. If I comment out the getUsers call in the ngInit function and uncomment the getUsersMock call, everything works fine and I see the data displayed in the listbox in the HTML page. I'd like to convert the JSON data to an array or list of Users in the service, rather then returning JSON from the service and having the component convert it.

Data returned from HTTP call to get users:

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

user.ts

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

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(): 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>
...

!!! UPDATE !!!

I had been reading the "heroes" tutorial, but wasn't working for me so I went off and tried other things. I've re-implemented my code the way the heroes tutorial describes. However, when I log the value of this.users, it reports undefined.

Here is my revised 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);
    }
...

Here is my revised 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();
    }
}
...

!!!!!!!!!! FINAL WORKING SOLUTION !!!!!!!!!! This is all the files for the final working solution:

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

解决方案

Take a look at your code :

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

and code from https://angular.io/docs/ts/latest/tutorial/toh-pt6.html (BTW. really good tutorial, you should check it out)

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

The HttpService inside Angular2 already returns an observable, sou don't need to wrap another Observable around like you did here:

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

Try to follow the guide in link that I provided. You should be just fine when you study it carefully.

---EDIT----

First of all WHERE you log the this.users variable? JavaScript isn't working that way. Your variable is undefined and it's fine, becuase of the code execution order!

Try to do it like this:

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


    }

See where the console.log(...) is!

Try to resign from toPromise() it's seems to be just for ppl with no RxJs background.

Catch another link: https://scotch.io/tutorials/angular-2-http-requests-with-observables Build your service once again with RxJs observables.

这篇关于从 Angular 服务获取对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆