2

I'm trying to get post data using http service in angular 2. and dont understand what wrong I'm doing here..
I'm using Plunker here
I've console.logged and it is showing this error. How to solve this this undefined?

Error:

ZoneAwareError
message
:"(SystemJS) TypeError: Cannot read property 'getPosts' of undefined↵ 
at execute     
(https://run.plnkr.co/YV2OxH7SpFuwfVbA/src/app.ts!transpiled:48:30)↵        
at ZoneDelegate.invoke  
(https://unpkg.com/zone.js@0.7.5/dist/zone.js:242:26)↵      at 
Zone.run (https://unpkg.com/zone.js@0.7.5/dist/zone.js:113:43)↵     at 
https://unpkg.com/zone.js@0.7.5/dist/zone.js:535:57↵        at 
ZoneDelegate.invokeTask 
(https://unpkg.com/zone.js@0.7.5/dist/zone.js:275:35)↵      at 
 Zone.runTask (https://unpkg.com/zone.js@0.7.5/dist/zone.js:151:47)↵        
at drainMicroTaskQueue 
(https://unpkg.com/zone.js@0.7.5/dist/zone.js:433:35)↵  Error loading  
 https://run.plnkr.co/YV2OxH7SpFuwfVbA/src/main.ts"
 name
 :
 "Error"

app.ts

//our root app component
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {HttpModule} from '@angular/http';
import {PostsService} from './posts';

@Component({
  selector: 'my-app',
  template: `
    <h3>Posts</h3>
    <div *ngFor="let post of posts | async">
        <h3>{{post.title}}</h3>
        <p>{{post.body}}</p>
    </div>
  `,
  providers: [PostsService]

})
export class App {
  posts:Post[];
  constructor(private postsService: PostsService) {
    this.name = 'Angular2'
  }

  this.postsService.getPosts().subscribe(posts => {
  this.posts = posts;
}

@NgModule({
  imports: [ BrowserModule, HttpModule ],
  declarations: [ App  ],
  bootstrap: [ App ]
})
export class AppModule {}

interface Post{
    id: number;
    title: string;
    body: string;
}

posts.ts

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class PostsService {
    constructor(private http: Http){
        console.log('PostsService Initialized...');
    }

    getPosts(){
    return this.http.get('https://jsonplaceholder.typicode.com/posts')
            .map(res => res.json());
    }
}

Here is plunker - https://plnkr.co/edit/jWaPbNlqsqXoOFFRzhhX?p=preview

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
Sushant
  • 87
  • 2
  • 11

2 Answers2

3

Sushant,

You need to subscribe in the body of a method -- the current location you are placing the code will be expected as a declaration and will be acted upon before the service is instantiated.

You have several options, here is one:

import {OnInit} from '@angular/core'
...
export class App implements OnInit {
  posts:Post[];
  constructor(private postsService: PostsService) {
    this.name = 'Angular2'
  }

  ngOnInit(){
    this.postsService.getPosts().subscribe(posts => {
      this.posts = posts;
    }
}

OnInit is called as a lifecycle hook when the component is instantiated, so you will be able to refer to the 'live' observable here.

Consider this link to the Angular 2 docs regarding lifecycle hooks: https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

chrispy
  • 3,552
  • 1
  • 11
  • 19
-1

Try this:

constructor(private postsService: PostsService) {
  this.postsService.getPosts().subscribe(posts => {
    console.log(posts);
    this.posts = posts;
  }
}
msanford
  • 11,803
  • 11
  • 66
  • 93
Yashveer Singh
  • 1,914
  • 2
  • 15
  • 23
  • 3
    [It is preferable to do this in `ngOnInit()` rather than in the `constructor()`](http://stackoverflow.com/questions/35763730/difference-between-constructor-and-ngoninit) – msanford Jan 13 '17 at 21:45
  • 1
    thanks this is what i mentioned in my comments before posting answer . – Yashveer Singh Jan 13 '17 at 22:48