The issue is a timing one. Since the service call is asynchronous, the data does not arrive immediately when the subscribe is called. Rather, when the response is returned from the service, the callback function defined as the argument to the subscribe method is then called.
That's why the console.log within the Subscribe works.
Here is a picture roughly outlining the order of the execution.

However, your code will retain the value when it is indeed retrieved.
So outside of the subscribe function, you just need to check for the existence of the value. Something like this:
if (this.sessionTrackers) { console.log(...) }
Or if you are binding to the data, you need to use *ngIf
or the safe navigation operator (?).
If you are using reactive forms, then you may want to separate setting up the form model (using FormBuilder) and setting the default values.
I have an example of reactive forms here: https://github.com/DeborahK/Angular2-ReactiveForms (check out the APM folder).
ngOnInit
ngOnInit(): void {
this.productForm = this.fb.group({
productName: ['', [Validators.required,
Validators.minLength(3),
Validators.maxLength(50)]],
productCode: ['', Validators.required],
starRating: ['', NumberValidators.range(1, 5)],
tags: this.fb.array([]),
description: ''
});
// Read the product Id from the route parameter
this.sub = this.route.params.subscribe(
params => {
let id = +params['id'];
this.getProduct(id);
}
);
}
This code sets up the reactive form and watches for changes to the route parameters. When the route parameter is set, it calls getProduct(id).
getProduct
getProduct(id: number): void {
this.productService.getProduct(id)
.subscribe(
(product: IProduct) => this.onProductRetrieved(product),
(error: any) => this.errorMessage = <any>error
);
}
This goes to get the data, somewhat similar to what you are doing. Notice that in the subscribe callback I'm calling another method: onProductRetrieved
.
onProductRetrieved
onProductRetrieved(product: IProduct): void {
if (this.productForm) {
this.productForm.reset();
}
this.product = product;
// Update the data on the form
this.productForm.patchValue({
productName: this.product.productName,
productCode: this.product.productCode,
starRating: this.product.starRating,
description: this.product.description
});
this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
}
Here is where I am setting the default values for the reactive form since I now know I have the data. You can use setValue
or patchValue
for this.