1

i'am new on Angular2 and i'am trying to get data from a json file. To do this i'am using Http with Promise but when i do console.log from my promise variable they return Undefined.

post.services.ts

import {Injectable} from '@angular/core';
import { Headers, Http, Response} from '@angular/http'; 
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/toPromise';
import {Post} from '../interfaces/post.interface';
@Injectable()
export class PostService{
    private url = 'myjson.json';
    constructor(private http: Http){ }
    private extractData(res: Response) {
      let body = res.json();
      console.log(body.data);
      return body.data || null;
    }
    getPosts(): Promise<Post[]>{
        return this.http.get(this.url)
            .toPromise()
            .then(this.extractData)
            .catch(this.handleError);
    }   
    private handleError(error: any) {
      console.error('An error occurred', error);
      return Promise.reject(error.message || error);
    }
}

posts.component.js

import { Component, OnInit } from '@angular/core';
import { Router }            from '@angular/router';
import {PostService} from '../services/post.service';
import {Post} from '../interfaces/post.interface';

@Component({
    selector: 'posts',
    template: 
    `
    <h1>Posts</h1>
    <form (submit)="addPost()">
        <label for="title">Title</label>
        <input type="text" [(ngModel)]="title" />
        <br />
        <label for="body">Body</label>
        <input type="text" [(ngModel)]="body" />
        <br />
        <input type="submit" value="Submit" />
    </form>
    <ul>
        <li *ngFor="let post of posts">
            {{1+1}}
            <h3>{{post.title}}</h3>
        </li>
    </ul>
    `,
})

export class PostsComponent implements OnInit{
    private posts:Post[];
    private title:string;
    private body:string;
    private newPost:Object;
    error: any;

    constructor(private _postService:PostService){}
    getPosts(){
        this._postService.getPosts().then(posts => this.posts = posts).catch(error => this.error = error);
    }
    ngOnInit() {        
        this.getPosts();
        console.log(this.posts);
    }
    addPost(){
        this.newPost={
            title:this.title,
            body:this.body
        }
    }
}

post.interface.ts

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

Please some one can help me? Thank you.

4
  • 1
    Please update your question with the specific code that you are having an issue with rather than make us hunt through your git repo. Commented Jul 19, 2016 at 13:55
  • 1
    I have edited the post. Sorry about that. Commented Jul 19, 2016 at 14:20
  • Now you have far too much irrelevant code posted. Please review minimal reproducible example Commented Jul 19, 2016 at 14:38
  • @charlietfl Thank you about that. Edited again. Commented Jul 19, 2016 at 14:49

1 Answer 1

6

It's because promises / HTTP requests are asynchronous. You need to add console.log within the callback of the promises for your HTTP request. If you do that outside this callback (i.e. right after executing the request), the response isn't there anymore so you'll have an undefined.

Here is a sample:

getPosts(){
    this._postService.getPosts().then(posts => {
      this.posts = posts;
      console.log(this.posts); // not null
    }).catch(error => this.error = error);
}

ngOnInit() {        
    this.getPosts();
    console.log(this.posts); // null
}

Edit

I think that the problem is in your extractData method. You shouldn't use body.data unless you have a data property in your JSON property.

    private extractData(res: Response) {
      let body = res.json();
      console.log(body);
      return body || null; // <-------
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Now return NULL but not the posts. I dont know why.
I think that the problem is in your extractData method. You shouldn't use body.data unless you have a data property in your JSON property. I updated my answer accordingly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.