Angular service - GET returns undefined

2019-07-13 20:58发布

I'm trying to use an angular service to get users from a database. When doing a GET request IN the service, I can console.log(res) and get the response. However, when I try to grab the data from another component, it always comes up undefined. Please help.

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

And when I try to use it in app.component.html ...

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

users comes up undefined

4条回答
SAY GOODBYE
2楼-- · 2019-07-13 21:33

The issue with your code is that you are returning within the subscription. Get is an async call Javascript doesn't know when it is going to return.

Quick Fix: Get the prop directly After you make the REST call.

in your service:

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

in your component:

usersService.getUsers();
this.users = usersService.users;
查看更多
戒情不戒烟
3楼-- · 2019-07-13 21:38

Your Service Class

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')
}

Your Component

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

Make sure to import { Observable }

查看更多
祖国的老花朵
4楼-- · 2019-07-13 21:43

If you are using your service to centralize your users data, then consider this:

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');

  }

}

then in your component:

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
  }

and in your template:

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

By making these changes, your getUsers() method will only be called at the creation time of your UsersService (first time it appears in providers array) and your users data will be available to any component that injects UsersService.

查看更多
欢心
5楼-- · 2019-07-13 21:43

Change your service as

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

and use subscribe() inside the component,

   this.usersService.getUsers().subscribe((data) => {
      this.users = data;
    });
查看更多
登录 后发表回答