1

I am working on learning Angular 4. I have written the service and the component. When I call the service I can get the data in the subscribe function, but it does not assign the data to the class variable. Here is my service.

import { Injectable } from "@angular/core";
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map'
import { Work } from '../shared/work'

import { API } from './../utils/api.data'

@Injectable()
export class WorkService {
    public api: API = new API();
    private api_url: string = this.api.url+'works/latest/2/';
    constructor(
        private http: Http
    ){
        
    }

    public getLatestWorks(): Observable<Work[]>{
        return this.http.get(this.api_url)
                .map((response:Response) => <Work[]>response.json()['data']);
            
    }
}

This is the component

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { WorkService } from './../work.service/work.service';
import { Work } from './../shared/work';

@Component({
  selector: 'latest_works',
  templateUrl: './latest.works.component.html',
  providers: [ WorkService ]
})
export class LatestWorksComponent implements OnInit { 
  public latest_works: Work[];
  public errorMessage: string;

  constructor(
    private workService: WorkService
  ){}

  private getLatestWorks(){
    this.workService.getLatestWorks()
        .subscribe(
          data => {
            this.latest_works = data
            console.log('data inside the subscribe ' + data);
            console.log('latest_works inside the subscribe ' + this.latest_works);
          },
          error => this.errorMessage = <any>error
        );

  }
 
  ngOnInit(){
    //console.log(this.latestworks());
    this.getLatestWorks();
    console.log('data ' + this.latest_works);
  }

}

Here is the output to the classes.

[Log] data undefined
[Log] Angular is running in the development mode. Call enableProdMode() to enable the production mode.
[Log] data inside the subscribe [object Object],[object Object]
[Log] latest_works inside the subscribe [object Object],[object Object]

Like I said I am new to angular and I have no idea what is truly going on right now. Any guidance would be great or any advice what I am doing wrong.

1
  • Can you check response data.. console.log('data inside the subscribe ' + data); what is the output for his ? Commented Oct 2, 2017 at 1:54

2 Answers 2

2

Your console.log in ngOnInit is undefined because the http request is asynchronous. When that console.log is fired, your code is still waiting for the response from the server, hence the undefined. You can see in the success callback of the subscribe, you have the server data. And you are storing the API result in your latest_works property.

this.latest_works = data; // response gets stored in class property
Sign up to request clarification or add additional context in comments.

4 Comments

SO does that mean I do have the data stored I just called the log before the server responded?
@John correct, the data is stored once the http request finishes. The console.log('data' + this.latest_works); is called before that finishes. I'd do some research on asynchronous code. Essentially your code runs the getLatestWorks method (which is asynchronous and doesn't block the rest of your JavaScript from running), then makes that data console.log
Is this the best way to do it?
@John that is a loaded question. But in architectural terms, asynchronous programming is definitely recommended. I would take a look at the async pipe, another way to subscribe to data. (angular.io/api/common/AsyncPipe)
1

Resolver is the solution you are looking for. Check this link https://angular.io/api/router/Resolve ;explanation and example.

When you change the state, the resolver will call the method with the http request; when the request is done, the router will change the state and the html content will be fetched when is loaded.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.