Angular2 - OnInit: values ​​returned from a subscription service are not bound to Component / s fields

I am testing Angular2 and following their tutorials.

I currently have a Service that receives data from a json server:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';

import { Observable } from 'rxjs/Observable';

import { User } from './user';

@Injectable()
export class UserService {
  constructor(private http: Http) {}

  private usersUrl = 'http://localhost:3000/users';

  getUsers(): Observable<User[]> {
    return this.http.get(this.usersUrl) //the request won't go out until something subscribes to the observable
                    .map(this.extractData)
                    .catch(this.handleError); // pass an error message back to the component for presentation to the user but only if we can say something the user can understand and act upon
  }

  private extractData(response: Response) {
    if (response.status < 200 || response.status >= 300) {
       throw new Error('Bad response status: ' + response.status);
    }
    let body = response.json(); // parse JSON string into JavaScript objects

    return body.data || { };
  }

  private handleError (error: any) {
    // In a real world app, we might send the error to remote logging infrastructure before returning/sending the error
   let errMsg = error.message || 'Server error'; // transform the error into a user-friendly message

   return Observable.throw(errMsg); // returns the message in a new, failed observable
  }

}

And my component:

import { Component, OnInit } from '@angular/core';

import { User } from '../common/user/user';
import { UserService } from '../common/user/user.service';

@Component({
  selector: 'app-nav',
  templateUrl: '/app/nav/nav.component.html',
  styleUrls: ['/app/nav/nav.component.css']
})
export class NavComponent implements OnInit {
  errorMsg: string;
  users: User[];

  constructor(private userService: UserService) { }

  getUsers() {
    this.userService
    .getUsers()
    .subscribe(
      function(users) {
        console.log('users ' + users);
        this.users = users;
        console.log('this.users ' + this.users);
      }, function(error) {
        console.log('error ' + error);
      });
    // users => this.users = users,
    // error => this.errorMsg = <any>error);
  }

  ngOnInit() {
    this.getUsers();
    console.log('ngOnit after getUsers() ' + this.users);
  }
}

My problem is that the data returned from the signed function is not transferred / not assigned to my users the component properties after the getUsers () call is completed. I know that the data is returned to the component from the service method call, because I can register the data in the userService () method. GetUsers. The strangest thing is that calling console.log on my ngOnInit is printed on my console dev first before console.logs in my getUsers method, although I call getUsers first:

  ngOnInit() {
    this.getUsers();
    console.log('ngOnit after getUsers() ' + this.users);
  }

Screenshot of the dev console:

+4
1

, this.getUsers(), this.userService.getUsers().subscribe(...) . , (console.log('ngOnit after getUsers() ' + this.users); , ), , subscribe().

, :

  getUsers() {
    return this.userService
    .getUsers()
    .map(
      (users) => {
        console.log('users ' + users);
        this.users = users;
        console.log('this.users ' + this.users);
      })
     .catch((error) => {
        console.log('error ' + error);
        throw error;
      });
    // users => this.users = users,
    // error => this.errorMsg = <any>error);
  }

  ngOnInit() {
    this.getUsers().subscribe(_ => {;
      console.log('ngOnit after getUsers() ' + this.users);
    });
  }

getUsers() map() , , , .

ngOnInit() subscribe() (subscribe() , http.get() ) , , .

function () () =>. , this () => { ... }, .

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

.

+7

All Articles