Reputation: 313
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
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
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