Angular service - GET returns undefined

2019-07-13 21:18发布

问题:

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

回答1:

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.



回答2:

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:

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


回答4:

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 }