Mitchell Hamann
Mitchell Hamann

Reputation: 313

Angular2.RC1 http observable not passing to component

Having some issues with getting the observable Array on my component receiving the data from my service.

The service loads fine, and I can see the objects. But the Component is not loading the data into the Blog Array.

Service Logic:

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

import { Blog } from '../models/blog.ts';


@Injectable()

export class BlogService {

    private blogsUrl:string = '/blog.json'

    constructor(
        private _http: Http
        ){}

    getBlogs(): Observable<Blog[]>{
        return this._http.get(this.blogsUrl)
            .map(this.extractData)
            .catch(this.handleError);
    }

    private extractData(res: Response) {
        let body = res.json();
        console.log(body);
        return body || {};
    }

    private handleError(error: any) {
        // In a real world app, we might use a remote logging infrastructure
        // We'd also dig deeper into the error to get a better message
        let errMsg = (error.message) ? error.message :
            error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
    }

}

Component Logic:

import { Component, OnInit } from '@angular/core';
import { config } from '../config';
import { BlogService } from './services/blog.srv'
import { Blog } from './models/blog';

@Component({
    selector: 'blog-component',
    templateUrl: config.templateUrl + './blog/views/blog.component.html',
    styleUrls: ['/assets/js/app/blog/styles/blog.component.css'], 
    providers: [
        BlogService
    ]
})

export class BlogComponent implements OnInit{
    public page = 'Blog';
    errorMessage: string;
    blogs: Blog[];
    mode = 'Observable';

    constructor(
        private _blogSrv: BlogService
            ){}

    ngOnInit() { 
        this.getBlogs();
    }

    getBlogs(){
        return this._blogSrv.getBlogs()
            .subscribe(
            blogs => this.blogs = blogs,
            error => this.errorMessage = <any>error);
    }

}

Am I misunderstanding how the observable works? Should it not load the blogs object with the return "body"

EDIT:

Main.ts:

/// <reference path="../typings/browser.d.ts" />

import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router';
import { HTTP_PROVIDERS } from '@angular/http';
import { AppComponent } from './app.component';


bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    HTTP_PROVIDERS
]); 

Upvotes: 1

Views: 69

Answers (2)

Mitchell Hamann
Mitchell Hamann

Reputation: 313

The issue here is that the view was not properly copied down to the public directory. with the new *ngFor.

Also the array was not being set to empty when declare so:

blogs:Blog[]; vs blogs:Blog[] = []

Now it works, verified with another section which uses similar logic.

Upvotes: 0

Thierry Templier
Thierry Templier

Reputation: 202326

Perhaps you forgot to specify HTTP_PROVIDERS when bootstrapping your application:

bootstrap(AppComponent, [ HTTP_PROVIDERS ]);

Otherwise, the code of both component and service looks fine.

Edit

Perhaps you could force Angular 2 to detect changes:

@Component({
  (...)
})
export class BlogComponent implements OnInit{
  public page = 'Blog';
  errorMessage: string;
  blogs: Blog[];
  mode = 'Observable';

  constructor(
    private _blogSrv: BlogService,
    private _cdr:ChangeDetectorRef
        ){}

  ngOnInit() { 
    this.getBlogs();
  }

  getBlogs(){
    return this._blogSrv.getBlogs()
        .subscribe(
        blogs => {
          this.blogs = blogs;
          this._cdr.detectChanges(); // <------
        },
        error => this.errorMessage = <any>error);
  }
}

Upvotes: 1

Related Questions