After running through many tutorials on tinterweb I have finally started to try and build something useful to me using Angular2 and I have come across my first issue. I cannot seem to load JSON data into my service component.
my people.json file is stored in a folder called data in the top folder.
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" }
]
I believe my issue lies in the friends.service.ts
friend.service.ts
import {Injectable} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';
@Injectable()
export class FriendService {
friends:Array<any>;
constructor(private http:Http)
{
//console.log(">>friend.service.ts:constructor--")
http.request('./data/people.json')
.subscribe(response => this.friends = response.json()));
}
getFriends()
{
//console.log(">>friend.service.ts:getFriends--")
console.log(this.friends)
return this.friends
}
}
friend.service.ts is used within the friend.component.ts
friend.component.ts
import { Component } from 'angular2/core';
import { FriendService } from 'app/friend.service';
@Component({
selector: 'my-friends',
providers: [FriendService],
styles: [`
div {
background-color:#EFEFEF;
margin-bottom:15px;
padding:15px;
border:1px solid #DDD;
box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
border-radius:3px;
}
h2 {
text-align: center;
}
`],
template: `
<h1>Hello from the {{ componentName }}!</h1>
<div *ngFor="#f of friends">
<h3>Name: {{ f.name }}</h3>
<h4>Age: {{ f.age }}</h4>
</div>
`
})
export class FriendComponent {
componentName: 'FriendComponent';
constructor(private _friendService: FriendService)
{
this.friends = _friendService.getFriends();
}
}
this lives within main.ts
main.ts
import { Component } from 'angular2/core';
import { bootstrap } from 'angular2/platform/browser';
import { FriendComponent } from 'app/friend.component';
import {HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'my-app',
directives: [FriendComponent],
styles: [`
h1 {
color:#545454;
background:#02A8F4;
padding:15px;
box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
}
`]
template: `
<div>
<h1>Hello from the {{componentName}}.</h1>
<my-friends></my-friends>
</div>
`
})
export class AppComponent {
componentName: 'AppComponent'
}
bootstrap(AppComponent,[HTTP_PROVIDERS])
...and here is the index page...
<!DOCTYPE html>
<html>
<head>
<script>document.write('<base href="' + document.location + '" />');</script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--Add Bootstrap CSS Styles-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<!-- IE required polyfills, in this exact order -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.1/es6-shim.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
<script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
<!-- Angular polyfill required everywhere -->
<script src="https://code.angularjs.org/2.0.0-beta.8/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.8/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.8/angular2.dev.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.8/router.dev.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.8/http.dev.js"></script>
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
packages: {
'api': {defaultExtension: 'ts'},
'app': {defaultExtension: 'ts'}
}
});
System.import('app/main')
.then(null, console.error.bind(console));
</script>
</head>
<body class="container">
<my-app>Loading...</my-app>
</body>
</html>
Any help would be greatly appreciated ;)
In fact, it's because your data are loaded asynchronously. So within the constructor of your component, you initially get an undefined value.
To keep your constructor like that, you need to refactor your code to make the
getFriends
method of your service return an observable:Then you can use the
async
pipe into your component template: