AngularJS 2 : Getting data from json file not working - json

I am trying to get the json data from an Angular service hero.service.ts. When using the fake http API inMemoryDataService, everything works fine and I am getting the json data from the in-memory-data.service.ts file. But when I try to get the data from a real json file, it does not work and I am getting an error 'collection not found' in the browser.
Here are the files contents (all 3 files are located in the app/ folder):
hero.service.ts :
import { Injectable } from '#angular/core';
import { Headers, Http , Response} from '#angular/http';
import 'rxjs/add/operator/toPromise';
import { Hero } from './hero';
#Injectable()
export class HeroService {
private heroesUrl = 'app/fakeListOfHeroes'; // URL to web api
//private heroesUrl = 'app/heroes.json'; // URL to JSON file
constructor(private http: Http) { }
getHeroes(): Promise<Hero[]>
{
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data)
.catch(this.handleError);
}
private handleError(error: any)
{
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
}
hero.service.ts :
export class InMemoryDataService {
createDb() {
let fakeListOfHeroes = [
{id: 11, name: 'Mr. Nice'},
{id: 12, name: 'Narco'},
{id: 13, name: 'Bombasto'},
{id: 14, name: 'Celeritas'},
{id: 15, name: 'Magneta'},
{id: 16, name: 'RubberMan'},
{id: 17, name: 'Dynama'},
{id: 18, name: 'Dr IQ'},
{id: 19, name: 'Magma'},
{id: 20, name: 'Tornado'}
];
return {fakeListOfHeroes};
}
}
heroes.json :
{
"data": [{
"id": 11,
"name": "Mr. Nice"
}, {
"id": 12,
"name": "Narco"
}, {
"id": 13,
"name": "Bombasto"
}, {
"id": 14,
"name": "Celeritas"
}, {
"id": 15,
"name": "Magneta"
}, {
"id": 16,
"name": "RubberMan"
}, {
"id": 17,
"name": "Dynama"
}, {
"id": 18,
"name": "Dr IQ"
}, {
"id": 19,
"name": "Magma"
}, {
"id": 20,
"name": "Tornado"
}]
}
Error in the browser:
error in browser
Any help would be appreciated. Thanks!

Found it ! It was due to the InMemoryBackendService and InMemoryDataService used in main.ts file, that seem to 'redirect' the calls from http.get method. Commenting those lines from main.ts file resolved the issue :
// Imports for loading & configuring the in-memory web api
import { XHRBackend } from '#angular/http';
//import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api';
//import { InMemoryDataService } from './in-memory-data.service';
// The usual bootstrapping imports
import { bootstrap } from '#angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '#angular/http';
import { AppComponent } from './app.component';
import { appRouterProviders } from './app.routes';
bootstrap(AppComponent, [
appRouterProviders,
HTTP_PROVIDERS
/*,
{ provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
{ provide: SEED_DATA, useClass: InMemoryDataService } // in-mem server data
*/
]);

Related

Unable to Parse JSON data in angular requested through API

I am trying to get the data of movie from imdb site with the help of an API but unable to process the data further.
Here is the link i pass ("https://sg.media-imdb.com/suggests/j/johnwick.json") in the get method and opening the browser it looks like this:
imdb$johnwick({
"v": 1,
"q": "johnwick",
"d": [
{
"l": "John Wick: Chapter 3 - Parabellum",
"id": "tt6146586",
"s": "Keanu Reeves, Ian McShane",
"y": 2019,
"q": "feature",
"vt": 5,
"i": [
"https://m.media-amazon.com/images/M/MV5BNDU3YzJlY2EtODA3NS00ZWM3LWJhYjUtZWE3MmE2YmEzNWYwXkEyXkFqcGdeQXVyNDMzMzI5MjM#._V1_.jpg",
4050,
6000
],
"v": [
{
"l": "Official Trailer",
"id": "vi3978017305",
"s": "2:18",
"i": [
"https://m.media-amazon.com/images/M/MV5BNTg2YzEyNjktMmRmZi00NjU4LWIxNzYtMGE0Y2U2MDI5Y2Q1XkEyXkFqcGdeQW1yb3NzZXI#._V1_.jpg",
1920,
1080
]
}
]
},
{
"l": "John Wick",
"id": "tt2911666",
"s": "Keanu Reeves, Michael Nyqvist",
"y": 2014,
"q": "feature",
"vt": 23,
"i": [
"https://m.media-amazon.com/images/M/MV5BMTU2NjA1ODgzMF5BMl5BanBnXkFtZTgwMTM2MTI4MjE#._V1_.jpg",
1365,
2048
],
"v": [
{
"l": "Trailer #2",
"id": "vi2273816345",
"s": "1:00",
"i": [
"https://m.media-amazon.com/images/M/MV5BMjU0OTQwMjUyN15BMl5BanBnXkFtZTgwODQ5OTE4MjE#._V1_.jpg",
640,
480
]
},
{
"l": "Clip",
"id": "vi3905924889",
"s": "0:29",
"i": [
"https://m.media-amazon.com/images/M/MV5BNDYwMTUwNTMyNF5BMl5BanBnXkFtZTgwNDcyMjExMzE#._V1_.jpg",
1280,
720
]
},
{
"l": "John Wick",
"id": "vi2809377049",
"s": "4:18",
"i": [
"https://m.media-amazon.com/images/M/MV5BNGQ1YjYwOTUtODRkOS00NjU3LWJjZTMtOWM1MWE2YmFiN2ZjXkEyXkFqcGdeQXVyNzU1NzE3NTg#._V1_.jpg",
480,
360
]
}
]
},
{
"l": "John Wick: Chapter 2",
"id": "tt4425200",
"s": "Keanu Reeves, Riccardo Scamarcio",
"y": 2017,
"q": "feature",
"i": [
"https://m.media-amazon.com/images/M/MV5BMjE2NDkxNTY2M15BMl5BanBnXkFtZTgwMDc2NzE0MTI#._V1_.jpg",
1328,
2048
]
},
{
"l": "John Williams",
"id": "nm0002354",
"s": "Music Department, Star Wars: Episode I - The Phantom Menace (1999)",
"i": [
"https://m.media-amazon.com/images/M/MV5BMjY5MTgzMTQ1NF5BMl5BanBnXkFtZTYwNDg3OTcz._V1_.jpg",
280,
400
]
},
{
"l": "John Witherspoon",
"id": "nm0936762",
"s": "Actor, Friday (1995)",
"i": [
"https://m.media-amazon.com/images/M/MV5BMTM2NTg4MDcxNV5BMl5BanBnXkFtZTYwMDAxMzY0._V1_.jpg",
317,
400
]
},
{
"l": "John Williams",
"id": "nm0002369",
"s": "Actor, Sabrina (1954)",
"i": [
"https://m.media-amazon.com/images/M/MV5BMTUyNDg1MTU5MV5BMl5BanBnXkFtZTcwMTgwNTUxOA##._V1_.jpg",
1107,
1426
]
},
{
"l": "John Wilder",
"id": "nm0928588",
"s": "Writer, Centennial (1978-1979)",
"i": [
"https://m.media-amazon.com/images/M/MV5BMjAxNjE0NzE1MV5BMl5BanBnXkFtZTcwNzUzNjI0NA##._V1_.jpg",
473,
650
]
},
{
"l": "John Wick Chapter 2: Wick-vizzed",
"id": "tt7161870",
"s": "Pedro Hollywood, J.J. Perry",
"y": 2017,
"q": "video",
"i": [
"https://m.media-amazon.com/images/M/MV5BNDNkZDI0MjktMmZiYS00ZjI4LWI3ZDctMTBhMTMyYjczMDhlXkEyXkFqcGdeQXVyODA1NjQ0OTY#._V1_.jpg",
2000,
3000
]
}
]
})
Here is my angular code (The service file):
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class MovieProviderService {
storeMovie: any[];
constructor(private http: HttpClient) { }
getmovies(): Observable<any>
{
return this.http.get('https://sg.media-imdb.com/suggests/j/johnwick.json');
}
}
The below code is the file getting served:
import { Component, OnInit } from '#angular/core';
import { MovieProviderService } from '../movie-provider.service';
#Component({
selector: 'app-movie-container',
templateUrl: './movie-container.component.html',
styleUrls: ['./movie-container.component.scss']
})
export class MovieContainerComponent implements OnInit {
constructor(private movieService: MovieProviderService) { }
ngOnInit() {
let obs = this.movieService.getmovies();
obs.subscribe(
(response)=>{
const data = response.json();
console.log(data);},
(error)=>{console.log(error)}
)
}
}
It is giving the parsing error on console of chrome like unable to parse JSON at position 0...
I can see that the JSON data is contained inside imdb$johnwick( JSON ). How to get rid of that or may be tell some other good way or some topics which i need to learn. THANKYOU
IMDB return data in JSONP format so here you need to import HttpClientModule and HttpClientJsonpModule into your module.
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
// Import relevant http modules
import { HttpClientModule, HttpClientJsonpModule } from '#angular/common/http';
import { AppComponent } from './app.component';
import { ExampleService } from './example.service';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
// Import relevant http modules
HttpClientModule,
HttpClientJsonpModule
],
providers: [ExampleService],
bootstrap: [AppComponent]
})
export class AppModule { }
model-provider.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class MovieProviderService {
storeMovie: any[];
constructor(private http: HttpClient) { }
getmovies(): Observable<any>
{
return this.http.jsonp('https://sg.media-imdb.com/suggests/j/johnwick.json', 'callback');
}
}
Hope this will help!
In the service.js pass the option to handle the response as "text". We want to handle the reformatting of the text response in the service so we do not need to account for this in every component.
Using /(?:^.*?(\{)|\)$)/gm replaces everything before the first { and the ending ). The gm is "global" and "multi-line" for matching and will only replace the text if these rules are matched. We will then replace with first capture group of the RegExp (if there is no capture group one $1 becomes a blank string).
I took this approach to ensure if the source passes valid JSON in the future we wont be breaking/replacing valid JSON.
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class MovieProviderService {
storeMovie: any[];
constructor(private http: HttpClient) { }
getmovies(): Observable<string>
{
return this.http.get('https://sg.media-imdb.com/suggests/j/johnwick.json', { responseType: 'text' })
.map((res) => {
return JSON.parse(res.replace(/(?:^.*?(\{)|\)$)/gm, "$1"));
});
}
}
import { Component, OnInit } from '#angular/core';
import { MovieProviderService } from '../movie-provider.service';
#Component({
selector: 'app-movie-container',
templateUrl: './movie-container.component.html',
styleUrls: ['./movie-container.component.scss']
})
export class MovieContainerComponent implements OnInit {
constructor(private movieService: MovieProviderService) { }
ngOnInit() {
let obs = this.movieService.getmovies();
obs.subscribe(
(response)=>{
const data = response; // no longer need to call .json()
console.log(data);},
(error)=>{console.log(error)}
)
}
}

ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed

I have issue with nested JSON file. I use primeNG templates dataTable and treeTable. When I try to access data via API call in console I can see data but in template I'm getting this error:
ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed
json file
{
"CategoryId": "257cf663-f6ba-40f7-69b8-08d527528e70",
"Name": "House Only",
"OverBudgetCalculator": true,
"Scopes": [
{
"ScopeId": 1,
"Name": "Budget",
"Question": {
"QuestionId": 1,
"Content": "What is your maximum budget ?",
"QuestionType": "range",
"Strict": true,
"NeutralScore": 10,
"Weight": 100,
"UpDownSelectionApplied": false,
"Active": true,
"RelatedProductFields": [
{
"RelatedProductFieldId": 3,
"FieldName": "Budget",
"Step": 1000,
"Min": 0,
"Max": 0
}
],
"Answers": []
}
},
{
"ScopeId": 2,
"Name": "Levels",
"Question": {
"QuestionId": 2,
"Content": "Do you want a single or double ?",
"QuestionType": "singleSelection",
"Strict": true,
"NeutralScore": 10,
"Weight": 95,
"UpDownSelectionApplied": false,
"Active": true,
"RelatedProductFields": [
{
"RelatedProductFieldId": 10,
"FieldName": "House_Only_Levels",
"Step": 0,
"Min": 0,
"Max": 0
}
],
"Answers": [
{
"AnswerId": 18,
"Title": "Double Story",
"Content": "Double Story",
"MatchRule": "Double",
"UpDownSpecifications": [],
"Selected": false
},
{
"AnswerId": 19,
"Title": "Single Story",
"Content": "Single Story",
"MatchRule": "Single",
"UpDownSpecifications": [],
"Selected": false
}
]
}
scope.service.ts
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from "#angular/http";
import { AppSessionService } from '#shared/common/session/app-session.service';
import { Observable } from 'rxjs/Observable';
import { Scope } from './scope';
import { TreeTableModule } from 'primeng/components/treetable/treetable';
#Injectable()
export class ScopeService {
constructor(
private http: Http,
private appSessionService: AppSessionService) { }
// GET api/categories/scopes/257CF663-F6BA-40F7-69B8-08D527528E70
getScopes(categoryId): Observable<any> {
let headers = new Headers({ 'Content-Type': 'application/json' })
let options = new RequestOptions({ headers: headers });
return this.http.get('/api/categories/' + categoryId)
.map((res: Response) => res.json())
.catch(this.handleErrorObservable);
}
private extractData(res: Response) {
let body = res.json();
return body.data || {};
}
private handleErrorObservable(error: Response | any) {
console.error(error.message || error);
return Observable.throw(error.message || error);
}
}
scope.component.ts
import { Component, Injector, OnInit, ViewChild } from '#angular/core';
import { AppComponentBase } from '#shared/common/app-component-base';
import { appModuleAnimation } from '#shared/animations/routerTransition';
import { ScopeService } from './scope.service';
import { DataTable } from 'primeng/components/datatable/datatable';
import { Paginator } from 'primeng/components/paginator/paginator';
import { TreeTableModule } from 'primeng/components/treetable/treetable';
#Component({
templateUrl: './scopes.component.html',
animations: [appModuleAnimation()]
})
export class ScopesComponent extends AppComponentBase implements OnInit {
errorMessage: String;
scopes: any = [];
categoryId: String = '257CF663-F6BA-40F7-69B8-08D527528E70';
constructor(
injector: Injector,
private scopeService: ScopeService
) {
super(injector);
}
ngOnInit(): void {
this.getScopes(this.categoryId);
}
getScopes(categoryId) {
this.scopeService.getScopes(categoryId).subscribe(values => {
this.scopes = values;
console.log(this.scopes);
})
}
}
This is component file with treeTable
scope.component.html (treeTable)
<p-treeTable [value]="scopes" [style]="{'margin-top':'50px'}">
<p-header>Editable Cells with Templating</p-header>
<p-column field="CategoryId" header="ScopeId">
<ng-template let-node="rowData" pTemplate="body">
<input type="text" [(ngModel)]="categories.Scopes.ScopeId" style="width:100%;border-width:0px 0px 1px 0px">
</ng-template>
</p-column>
<p-column field="Name" header="Name">
<ng-template let-node="rowData" pTemplate="body">
<input type="text" [(ngModel)]="categories.Scopes.Name" style="width:100%;border-width:0px 0px 1px 0px">
</ng-template>
</p-column>
</p-treeTable>
This is component file with dataDatable.
scope.components.html (dataTable)
<p-dataTable [value]="scopes"
selectionMode="single"
[rows]="10"
[responsive]="true">
<p-column field="Scopes" header="Scope name">
<ng-template let-account="rowData" pTemplate="body">
<ul>
<li *ngFor="let scope of categories.scopes">
{{scope.ScopeId}} - {{scope.Name}}
</li>
</ul>
</ng-template>
</p-column>
</p-dataTable>
When I use dataTable option I'm getting different error.
ERROR TypeError: val.slice is not a function
enter image description here
enter image description here

Angular map function is returning "undefined is not a function"

I'm following this tutorial https://www.barbarianmeetscoding.com/blog/2016/04/02/getting-started-with-angular-2-step-by-step-6-consuming-real-data-with-http/, with Angular2 and VS Code.
I created a db.json server to test an api with, with the test data looking like
{
"articles": [{
"id": 1,
"name": "Wand of Lightning",
"description": "A powerful wand of ligthning.",
"price": 50,
"imageUrl": "/assets/images/wand.png",
"specs": [{
"name": "weight",
"value": 10
}, {
"name": "height",
"value": 22
}, {
"name": "material",
"value": "wood"
}],
"reviews": [{
"author": "Jaime",
"title": "I loved it!",
"content": "I loved the wand of ligthning! I usually use it to charge my laptop batteries!",
"rating": 5
}, {
"author": "John Doe",
"title": "Underwhelming",
"content": "I didn't like it at all...",
"rating": 1
}]
}, {
"id": 2,
"name": "Staff of Fire",
"description": "A powerful staff of fire.",
"price": 150,
"imageUrl": "/assets/images/staff-of-fire.png",
"specs": [{
"name": "weight",
"value": 10
}, {
"name": "height",
"value": 22
}, {
"name": "material",
"value": "wood and alabaster"
}],
"reviews": [{
"author": "Jaime",
"title": "I loved it!",
"content": "I loved the wand of ligthning! I usually use it to charge my laptop batteries!",
"rating": 5
}, {
"author": "John Doe",
"title": "Underwhelming",
"content": "I didn't like it at all...",
"rating": 1
}]
}
Now if I try to adapt my code to the sample, I get
undefined is not a function
Here's items.component.ts
import { Component, OnInit } from '#angular/core';
import {ItemsService} from '../items.service';
import {Item} from '../item';
#Component({
selector: 'app-items',
templateUrl: './items.component.html',
styleUrls: ['./items.component.css']
})
export class ItemsComponent implements OnInit {
items: Item[] = [];
errorMessage: string = '';
isLoading: boolean = true;
constructor(private itemsService: ItemsService) { }
ngOnInit() {
this.itemsService
.getAll().
subscribe(
p => this.items =p,
e => this.errorMessage = e,
/* onCompleted */ () => this.isLoading = false
)
}
}
items.service.ts
import { Injectable } from '#angular/core';
import { Http, Response, RequestOptions, Headers } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import {Item} from './item';
#Injectable()
export class ItemsService {
private baseUrl: string ='http://localhost:3000';
constructor(private http: Http) {
}
getAll(): Observable<Item[]>{
let items = this.http
.get(`${this.baseUrl}/articles`, { headers: this.getHeaders()})
.map(this.mapItems)
.catch(this.handleError);
return items;
}
private getHeaders(){
let headers = new Headers();
headers.append('Accept', 'application/json');
return headers;
}
mapItems(response:Response): Item[]{
return response.json().map(this.toItem)
}
toItem(r:any): Item{
let result = <Item>({
id: r.id,
name: r.name,
description: r.description,
price: r.price,
imageUrl: r.imageUrl,
});
console.log('Parsed item:', result);
return result;
}
// this could also be a private method of the component class
handleError (error: any) {
// log error
// could be something more sofisticated
let errorMsg = error.message || `Yikes! There was a problem with our hyperdrive device and we couldn't retrieve your data!`
console.error(errorMsg);
// throw an application level error
return Observable.throw(errorMsg);
}
}
Note: making
return response.json().map(this.toItem)
Into
return response.json()
works. But I would like to get map working.
EDIT: Screenshot
this will solve your issue -
getAll(): Observable<Item[]> {
const items = this.http
.get(`${this.baseUrl}/articles`, {headers: this.getHeaders()})
.map((response: Response) => this.mapItems(response.json()))
.catch(this.handleError);
return items;
}
mapItems(data: Array<any>): Item[] {
return data.map(item => this.toItem(item));
}
I think what you want to map (Array.prototype.map) is the articles in your response object, and not the object itself. Do this:
mapItems(response:Response): Item[]{
return response.json().articles.map(this.toItem)
}

parsing json data into objects with type script

My json data:
{
"status": "OK",
"data": {
"id": 3,
"initials": "mci",
"nom": "chabli",
"prenom": "mohammed Yassin",
"password": "m1ltRoJZRS",
"username": "yassine.chabli#edu.umi.ac.ma",
"photo": null,
"enabled": true,
"roles": [{
"id": 2,
"roleName": "DP",
"topSupression": false,
"lesGrilles": [{
"id": 2,
"affecte": true,
"privilege": {
"id": 1,
"actionName": "AjouterAVV"
}
},
{
"id": 3,
"affecte": true,
"privilege": {
"id": 2,
"actionName": "ModifierAVV"
}
}
]
},
{
"id": 3,
"roleName": "CP",
"topSupression": false,
"lesGrilles": [{
"id": 4,
"affecte": true,
"privilege": {
"id": 1,
"actionName": "AjouterAVV"
}
},
{
"id": 5,
"affecte": true,
"privilege": {
"id": 2,
"actionName": "ModifierAVV"
}
}
]
}
],
"departement": {
"id": 1,
"libelle": "Software",
"topSupression": false,
"area": {
"id": 1,
"libelle": "Maroc",
"topSupression": false
}
}
},
"error": null
}
I get this data successfully in my angular component like this:
import {AfterContentInit, Component, OnInit} from '#angular/core';
import {UserService} from '../services/user.service' ;
import {User} from '../classes/user' ;
import {Departement} from '../classes/departement';
import {Region} from '../classes/region';
import {Role} from '../classes/role';
import {Grille} from '../classes/grille';
import {Privilege} from '../classes/privilege';
#Component({
selector: 'rb-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: User = new User() ;
dept: Departement = new Departement();
area: Region = new Region();
roles: Role[] ;
grilles: Grille[];
privilege: Privilege
status: string ;
error: string;
constructor(public _us: UserService ) {
}
ngOnInit() {
this._us.getOneUser().subscribe(
data => (this.user = data.data, this.status = data.status, this.error = data.error , this.dept = this.user.departement,
this.area = this.dept.area , this.roles = this.user.roles),
error => alert(error),
() => console.log(this.roles)
);
}
}
In my HTML view I try to show some attribute like {{user.username }} it works.
But when I try to show like user.roles[0].id or something like that I have some error in the console:
the property id is undefined
While when I'm logging the user variable in the console, I can see that the property id of my roles array exist.

Why does my JSON not load in Angular 2

I am trying to load some JSON data into an Angular 2 Component, but I am getting an error of 'unexpected token :' It seems to not understand what my json data is.
I have tried to complete this 'simple' task many times yet I have as yet been unable to do so, so I hope I can get somewhere this time with the communities help...
Here is my code:
index.html
<!DOCTYPE html>
<html>
<head>
<script>document.write('<base href="' + document.location + '" />');</script>
<title>Angular 2 QuickStart</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
<!-- 1. Load libraries -->
<!-- IE required polyfills, in this exact order -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<!-- 2. Configure SystemJS -->
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
packages: {
app: { // must match your folder name
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app/main')
.then(null, console.error.bind(console));
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
main.ts
import {bootstrap} from 'angular2/platform/browser';
import {Http, HTTP_PROVIDERS} from 'angular2/http';
import {AppComponent} from './app.component';
import { PeopleService } from './people.service';
import 'rxjs/Rx';
bootstrap(AppComponent, [HTTP_PROVIDERS,PeopleService]);
app.component.ts
import {Component} from 'angular2/core';
import {ListComponent} from './list.component';
#Component({
selector: 'my-app',
directives : [ListComponent],
template: '<h1>{{applicationTitle}}</h1><my-list></my-list>'
})
list.component.ts
import {Component} from 'angular2/core';
import {HTTP_PROVIDERS} from 'angular2/http';
import {PeopleService} from './people.service'
import {Person} from './person'
#Component({
selector: 'my-list',
providers:
[
HTTP_PROVIDERS,
PeopleService,
],
template: `
<h2>This is the List component</h2>
<div *ngFor="#person of people">
<h2>{{person.name}}</h2>
<h3>{{person.age}}</h3>
</div>
`
})
export class ListComponent
{
people : Array<Person>
constructor(private _personService:PeopleService)
{
_personService.getPeople()
.subscribe(response => this.people = response);
}
}
people.service.ts
import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Person} from './person';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class PeopleService {
constructor(private http: Http) { }
private dataURL = './app/people.json';
getPeople(): Observable<Person[]> {
return this.http.get(this.dataURL)
.map(this.onSuccess)
.catch (this.onFail);
}
private onSuccess(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
return body.data || { };
}
private onFail(error: any) {
let errMsg = error.message || 'Server error';
console.error(errMsg);
return Observable.throw(errMsg);
}
}
person.ts
export class Person()
{
age: number;
name: string;
}
people.json
"people":[
{ age: 40, name: "Jordan Houston" },
{ age: 38, name: "Robert Eastham" },
{ age: 23, name: "Josh Beh" },
{ age: 23, name: "Joseph Canina" },
{ age: 24, name: "Alexandra Wilkins" },
{ age: 22, name: "Kiersten Costanzo" },
{ age: 23, name: "Ku Sherwood" },
{ age: 25, name: "Arta Halili" },
{ age: 24, name: "Patrick Cooney" },
{ age: 23, name: "Z.A. Perr" },
{ age: 18, name: "Tyler Mulligan" },
{ age: 26, name: "Dennis Dempsey" },
{ age: 32, name: "Francis Yeager" },
{ age: 23, name: "Phil Belardi" }
]
The actual error is as follows:
people.service.ts:32 Unexpected token :System.register.context_1.execute.PeopleService.onFail # people.service.ts:32CatchSubscriber.error # Rx.js:3239MapSubscriber._next # Rx.js:5041Subscriber.next # Rx.js:10667onLoad # http.dev.js:660ZoneDelegate.invokeTask # angular2-polyfills.js:365NgZoneImpl.inner.inner.fork.onInvokeTask # angular2.dev.js:2103ZoneDelegate.invokeTask # angular2-polyfills.js:364Zone.runTask # angular2-polyfills.js:263ZoneTask.invoke # angular2-polyfills.js:431
angular2.dev.js:23887 EXCEPTION: Unexpected token :
my apologies for the formatting on the error
Changing the json format to the following
{
"people":[
{ "age": 40, "name": "Jordan Houston" },
{ "age": 38, "name": "Robert Eastham" },
{ "age": 23, "name": "Josh Beh" },
{ "age": 23, "name": "Joseph Canina" },
{ "age": 24, "name": "Alexandra Wilkins" },
{ "age": 22, "name": "Kiersten Costanzo" },
{ "age": 23, "name": "Ku Sherwood" },
{ "age": 25, "name": "Arta Halili" },
{ "age": 24, "name": "Patrick Cooney" },
{ "age": 23, "name": "Z.A. Perr" },
{ "age": 18, "name": "Tyler Mulligan" },
{ "age": 26, "name": "Dennis Dempsey" },
{ "age": 32, "name": "Francis Ye"age"r" },
{ "age": 23, "name": "Phil Belardi" }
]
}
changes the error to :
angular2.dev.js:23877 EXCEPTION: Unexpected token a
You JSON content isn't well-formed. You should use this:
{
"people":[
{ "age": 40, "name": "Jordan Houston" },
(...)
]
}
Don't forget " around property names.
Your PeopleService is returning body.data, but in your json file doesn't come up with that property. Try wrapping everything up into a data property in your json file, or change your PeopleService so that it doesn't return body.data anymore, but only body (or body.people in your case).
Also note the bad quotes on Francis Yeager.