2

I have a strange scenario where when I assign my local variable to a value coming from service it prints in the consol undefined , however, in the html template it prints the value.

app.component.ts

import { Component, OnInit,Input,ElementRef} from '@angular/core';
import { NavMenuService } from './navmenu/navMenu.service';
import { AppParamasService } from './shared/app-params.service';


@Component({
    selector: 'pm-app',
    moduleId: module.id,
    templateUrl: 'app.component.html',
    providers: [NavMenuService]
})
export class AppComponent implements OnInit {
        pageTitle: any[];
    title: string;
    id: number;
    errorMessage: string;
    constructor(private _navMenuService: NavMenuService, elm: ElementRef, private _appParams: AppParamasService) {

       somecode...
    }

    ngOnInit(): void {

        this._navMenuService.getLinkName(9999)
            .subscribe(
            data => {
                this.id = data.result.LinkID;
                this.title = data.result.LinkName;

            },
            error => this.errorMessage = <any>error);

        this._appParams.SetLinkID = this.id;//value is undefined
        console.log('app component linkid   ' + this.id);



    }

}

I also tried to put the set inside

this._navMenuService.getLinkName(9999)
            .subscribe(
            data => {
                this.id = data.result.LinkID;
                this.title = data.result.LinkName;

                this._appParams.SetLinkID = this.id;//value is undefined
        console.log('app component linkid   ' + this.id);

            },
            error => this.errorMessage = <any>error);

it only work if i hard code the value like this

this.id=9;
this._appParams.SetLinkID = this.id;
console.log('app component linkid   ' + this.id);

in app.component.html the values are showing up!!

{{id}}

{{title}}

app-params.service //this is a shared service so values should be available to other components

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import { IAppParams } from './app-params';

@Injectable()


export class AppParamasService {


    params: IAppParams;
    constructor() {

    }

    private _linkID: number;
    get LinkID(): number {
        return this._linkID;
    }
    set SetLinkID(value: number) {
        this._linkID = value;
    }

    private _gwLinkID: number;
    get GWLinkID(): number {
        return this._gwLinkID;
    }
    set SetGWLinkID(value: number) {
        this._gwLinkID = value;
    }


    GetParams() {
       return this.params;
    }

    private handleError(error: Response) {
        console.error(error);
        return Observable.throw(error.json().error || 'Server Error');
    }
}

why my this.id is undefined?

keep in mind if i put the message inside the method I see the values. If I check the value outside all values are lost. saame issue with this.title and this.titleID

this._navMenuService.getLinkName(this.linkID)
            .subscribe(
            data => {
                 this.titleID = data.result.LinkID;
                 this.title = data.result.LinkName;
                 this.titleIDString = data.result.LinkName;
                 //all values are printing correctly 
                 console.log('app component link id ' + this.titleIDString);
                 console.log('app component title ' + this.title);
                 console.log('app component link id data' + this.titleID);
            },
            error => this.errorMessage = <any>error);
           //all are undefined
        console.log('app component outside loop link id ' + this.titleIDString);
        console.log('app component outside loop title ' + this.title);
        console.log('app component outside loop link id ' + this.titleID);

I am trying to store titleID so other components can access it

ngOnInit(): void {

        this._navMenuService.getLinkName(this.gwLinkID)
            .subscribe(
            data => {
                this.titleID = data.result.LinkID;
                this._appParams.SetLinkID = data.result.LinkID;
                this.title = data.result.LinkName;

                console.log('nav inside link id ' + data.result.LinID);
                console.log('nav inside link id ' + this.titleID );

            },
            error => this.errorMessage = <any>error),

            console.log('nav outside link id ' + this.titleID);
           console.log('nav outside ' + this.title);

            this._appParams.SetParams(this.psnlUID, this.ntName, this.gwLinkID);




            this._navMenuService.getTabs(this._appParams.LinkID, 'xxxx')
            .subscribe(
            data => {
                this.tabs = data.result
            },
            error => this.errorMessage = <any>error),
            this.appParams = this._appParams.GetParams();







    }

this._appParams.LinkID is null and this is an issue

3
  • You should check for if data.result.LinkID has data and if it is number. Commented Jan 18, 2017 at 6:06
  • yes, just modified my code to make my issue more clear Commented Jan 18, 2017 at 16:55
  • an update/ideas on this issue? Commented Jan 19, 2017 at 17:57

1 Answer 1

2

I think you are dealing with an async problem. As you state in your question that outside the subscription the values are undefined, which is true. This is an async operation, so the code outside the subscription gets executed before the code inside the subscription, causing it to be undefined.

this._navMenuService.getLinkName(this.linkID)
            .subscribe(
            data => {
                 // this is executed later than outside subscribe
                 this.titleID = data.result.LinkID;
                 console.log('app component link id data' + this.titleID);
            },
            error => this.errorMessage = <any>error);
           //code here gets executed before inside subscription!
           console.log('app component outside loop link id ' + this.titleID);

EDIT: So now seeing your code, one solution is just to chain all those requests:

Where your ngOnInit calls the first method, and inside the subscription the other method for retrieving the tabs is called.

ngOnInit(): void {
    this._navMenuService.getLinkName(this.gwLinkID)
        .subscribe(
        data => {
            this.titleID = data.result.LinkID;
            this._appParams.SetLinkID = data.result.LinkID;
            this.title = data.result.LinkName;
            this._appParams.SetParams(this.psnlUID, this.ntName, this.gwLinkID);
            this.getTabs(); // call the tabs-method here, data is available here!
        });
}

And outside your ngOnInit:

getTabs() {
    this._navMenuService.getTabs(this._appParams.LinkID, 'xxxx')
        .subscribe(
        data => {
            this.tabs = data.result;
            this.appParams = this._appParams.GetParams();
        });
}
Sign up to request clarification or add additional context in comments.

6 Comments

I am abit confused because in the html this display the value {{titleID}} . I just need the this.titleID after the method so i can pass this value to another service. when i used {{titleID?}} i got this error "{{titleID?}} at the end of the expression [{{titleID?}} at the end of the expression [{{titleID?}}]".
Well if you are passing it to a service, why not do it inside the subscription?
I just updated my answer, so haven't looked at your sample yet :)
Updated answer again. Just chain them properly, this should work :)
THANK YOU AJT very much, It worked. Just so I understand for future cases .. data returned from services(like getLinkName) is available outside ngOnInt() for other methods?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.