【问题标题】:Angular service - GET returns undefinedAngular 服务 - GET 返回未定义
【发布时间】:2018-01-11 05:32:09
【问题描述】:

我正在尝试使用角度服务从数据库中获取用户。在服务中执行 GET 请求时,我可以console.log(res) 并获得响应。但是,当我尝试从另一个组件中获取数据时,它总是出现undefined。请帮忙。

users.service.ts

import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpClient, HttpClientModule } from '@angular/common/http';

@Injectable()
export class UsersService {

  constructor(
    private http: HttpClient,
    private route: ActivatedRoute
  ) { }

  users: any;

  getUsers() {
    this.http.get('http://localhost:3000/api/users').subscribe(res => {
      this.users = res;
      return this.users;
    });
  }

}

app.component.ts

import { UsersService } from './users.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  providers: [ UsersService ]
})

constructor(
    private http: HttpClient,
    private route: ActivatedRoute,
    private usersService: UsersService
  ) {
    this.users = usersService.getUsers();
  }

当我尝试在 app.component.html 中使用它时...

<div *ngFor="let user of users"></div>

用户出现未定义

【问题讨论】:

    标签: angular express service


    【解决方案1】:

    如果您使用您的服务来集中您的用户数据,请考虑以下事项:

    import { Injectable } from '@angular/core';
    import { ActivatedRoute } from '@angular/router';
    import { HttpClient, HttpClientModule } from '@angular/common/http';
    
    @Injectable()
    export class UsersService {
    
      constructor(
        private http: HttpClient,
        private route: ActivatedRoute
      ) {
         this.getUsers()
              .subscribe(data => this.users = data);
      }
    
      users: any;
    
      getUsers() {
        return this.http.get('http://localhost:3000/api/users');
    
      }
    
    }
    

    然后在你的组件中:

    constructor(
        private http: HttpClient,
        private route: ActivatedRoute,
        public usersService: UsersService <------ changed to public to make it available to the template
      ) {
         // this.users = usersService.getUsers(); <------ commented out, as users is now centralized in the service
      }
    

    在你的模板中:

    <div *ngFor="let user of usersService.users"></div>
    

    通过进行这些更改,您的 getUsers() 方法将仅在创建 UsersService 时调用(首次出现在提供程序数组中),并且您的用户数据将可供任何注入 UsersService 的组件使用。

    【讨论】:

    • 这似乎是最干净的方法,但它返回未定义。此外, res.json() 是多余的,因为响应是 json(许多其他帖子显示为已过时),即使将 res.json() 替换为 this.users = data,它仍然会在我的组件中返回 undefined .
    • @JarekOstrowski 你是对的 - 根据你使用的 HttpClient / HttpModule , .map(...) 可能是多余的。改变这个 .subscribe(data => this.users = data);到 .subscribe(data => console.log(data));并告诉我们您在控制台中看到的内容。
    • 是的,我在服务中的订阅内收到数据。一旦我尝试从组件中获取它,它就会出现未定义。不知道为什么它不把它拉进去。
    • @JarekOstrowski 我可以看到上面的代码和我的工作代码之间的唯一区别是提供程序数组。在我的 app.component.ts 中,providers 数组是空的,共享服务在 app.module.ts providers 数组中。否则,此实现没有问题。
    • @JarekOstrowski 如果您尝试从您的应用程序组件中执行 console.log(usersService.users),请注意您可能会在获取用户之前打印用户,因此未定义。
    【解决方案2】:

    您的代码的问题是您在订阅中返回。 Get 是一个异步调用 Javascript 不知道它什么时候返回。

    快速修复: 在进行 REST 调用后直接获取道具。

    为您服务:

    this.http.get('http://localhost:3000/api/users').subscribe(res => {
          this.users = res;
        });
    

    在您的组件中:

    usersService.getUsers();
    this.users = usersService.users;
    

    【讨论】:

    • 返回未定义。
    • 一开始是未定义的,因为它是一个异步操作。当您的异步调用解决时,它将使用数据更新您的用户对象。
    【解决方案3】:

    将您的服务更改为

     getUsers() {
        return this.http.get('http://localhost:3000/api/users')
          .map((response: Response) => response.json());
      }
    

    并在组件内使用 subscribe()

       this.usersService.getUsers().subscribe((data) => {
          this.users = data;
        });
    

    【讨论】:

    • 对不起,你应该使用 this.users = data;
    • 我正在尝试将所有内容保留在服务中。如果我只是在每个组件中获得 GET 请求,那么必须订阅我需要数据的每个组件所做的工作量是相同的。我要调用 this.users,而不必在我需要数据的每个组件中订阅或运行函数。
    【解决方案4】:

    您的服务等级

    import { Injectable } from '@angular/core';
    import { ActivatedRoute } from '@angular/router';
    import { HttpClient, HttpClientModule } from '@angular/common/http';
    
    @Injectable()
    export class UsersService {
    
    constructor(private http: HttpClient, private route: ActivatedRoute) { }
    
    getUsers(): Observable<any> {
        return this.http.get('http://localhost:3000/api/users')
        .map(res => res.json())
        .catch(this.handleError);
       }
    }
    
    private handleError(error: Response) {
        return Observable.throw(error || 'Server Error')
    }
    

    你的组件

    import { UsersService } from './users.service';
    
    @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
    providers: [ UsersService ]
    })
    
    constructor(private http: HttpClient, private route: ActivatedRoute, private usersService: UsersService) {
        this.usersService.getUsers().subscribe(
            res => { this.users = res; },
            err => { console.log(err); }
        );
    }
    

    确保导入{ Observable }

    【讨论】:

    • 出现未定义。
    • 尝试捕捉错误,我将代码更新为 handleError。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    相关资源
    最近更新 更多