Reputation: 832
My service is returning a Map. Now I want to use one of the values in my template but it won't show and I don't understand why.
I've created an example:
1 value is set via the constructor which is shown, the other 2 via an observable. The first one ('myKey') is shown the other one isn't.
@Injectable()
export class MessageService {
loadTestData(): Observable<Map<string, string>> {
const testData = new Map<string, string>();
testData.set('mySecondKey', 'mySecondValue');
testData.set('myThirdKey', 'myThirdValue');
return Observable.of(testData);
}
}
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<h3>Shown: {{test.get('myKey')}}</h3>
<h3>Not shown: {{test.get('mySecondKey')}}</h3>
<h3>Map size: {{test.size}}</h3>
</div>
`,
})
export class App implements OnInit {
name:string;
test: Map<string, string> = new Map<string, string>();
constructor(private messageService: MessageService) {
this.name = `Angular! v${VERSION.full}`
this.test.set('myKey', 'myValue');
}
ngOnInit() {
this.messageService.loadTestData().subscribe(data => {
this.test = data;
});
}
}
https://plnkr.co/edit/6mUieUMJTSvekiNxEuU3
Upvotes: 0
Views: 155
Reputation: 1920
Actually the code is perfectly fine with one exception - missing import of import { Observable } from 'rxjs/Rx';
. Seems like current SystemJS configuration is swallowing the errors.
Here is updated plnkr - https://plnkr.co/edit/WyQzOos0IOnvRZkzWSRS?p=preview
Upvotes: 2
Reputation: 3202
This is because you are not waiting for the subscribed data abd trying to render it before the value arrives.Modify your code as follow
In your component declare a boolean variable
private dataAvailable:boolean=false;
And toggle the value once the data is available
ngOnInit() {
this.messageService.loadTestData().subscribe(data => {
this.test = data;
this.dataAvailable=true;
});
}
and in the template ,wait for the value
<div *ngIf="dataAvailable">
<h2>Hello {{name}}</h2>
<h3>Shown: {{test.get('myKey')}}</h3>
<h3>Not shown: {{test.get('mySecondKey')}}</h3>
<h3>Map size: {{test.size}}</h3>
</div>
It should do the trick.You can as well use async pipe for achieving the same .You can find the docs here.Hope it helps
Upvotes: 0