Rey
Rey

Reputation: 1433

Passed-in Values Not Available at Run-time of Function in Angular App

I realize there is something I'm missing in terms of how and specifically when the products of certain functions are available in JavaScript.

In my Angular app, in order to get a user's initials, I am parsing data being returned from the API, and retrieving the first letter of the firstName, as well as the first letter of lastName in two different functions. These two functions are working as expected, and I can see the correct results in the console:

getFirstNameFirstLetter() {
    if (this.authenticationService.isAuthenticated()) {
        const userObj = JSON.parse(sessionStorage.getItem('currentUser'));
        const userInfo = userObj.data;
        const firstName = userInfo.name.first;
        const firstNameFirstLetter = firstName.trim().charAt(0);
        console.log(firstNameFirstLetter);
        return firstNameFirstLetter;
    }
}

getLastNameFirstLetter() {
    if (this.authenticationService.isAuthenticated()) {
        const userObj = JSON.parse(sessionStorage.getItem('currentUser'));
        const userInfo = userObj.data;
        const lastName = userInfo.name.last;
        const lastNameFirstLetter = lastName.trim().charAt(0);
        console.log(lastNameFirstLetter);
        return lastNameFirstLetter;
    }
}

Now comes the part I'm not fully understanding. When I then pass the returned values of these two functions, in order to get the initials, like this:

getInitials(firstNameFirstLetter, lastNameFirstLetter) {
    if (this.authenticationService.isAuthenticated()) {
        if (!this.firstNameFirstLetter || !this.lastNameFirstLetter) {
            console.log('Names not ready!');
            return;
        } else if (this.firstNameFirstLetter && this.lastNameFirstLetter) {
            console.log(firstNameFirstLetter + lastNameFirstLetter);
            return firstNameFirstLetter + lastNameFirstLetter;
        }
    }
}

... I get "Names not ready!" printed to the console each time.

By the way, I am running these functions within Angular's ngOnInit life cycle hook, like this:

ngOnInit() {
    this.getFirstNameFirstLetter();
    this.getLastNameFirstLetter();
    this.getInitials(this.firstNameFirstLetter, this.lastNameFirstLetter);
}

I know this has something to do with what's available when, because I get 'undefined' when I use break points and debug the two values being passed into the "getInitials()" function. In other words, the function doesn't have access to the returned values of the other two functions at the time it's run -- hence I'm getting 'Names not ready!' printed to the console. My question is, what am I missing, architecturally, to resolve this kind of issue?

Upvotes: 0

Views: 29

Answers (1)

Joo Beck
Joo Beck

Reputation: 1913

So what is happening here is that JavaScript doesn't think you are using the return values for getFirstNameFirstLetter and getLastNameFirstLetter, so when it makes the call, instead of waiting for that call to finish, it goes on to the next one, which introduces a race condition. if you simply change it to

ngOnInit() {
    let temp1 = this.getFirstNameFirstLetter();
    let temp2 = this.getLastNameFirstLetter();
    this.getInitials(this.firstNameFirstLetter, this.lastNameFirstLetter);
}

then it will wait for the previous functions to finish before calling the next.


Also, I don't use const very often, so I could be wrong and it could follow different scope rules, but by normal scope rules, setting a variable in that function, it is only available in that function, you would need to set it as

this.firstNameFirstLetter = firstName.trim().charAt(0);

to have access to it outside the function.


Or, so as to kill two birds with one stone, you could do

ngOnInit() {
    this.firstNameFirstLetter = this.getFirstNameFirstLetter();
    this.lastNameFirstLetter = this.getLastNameFirstLetter();
    this.getInitials(this.firstNameFirstLetter, this.lastNameFirstLetter);
}

or

ngOnInit() {
    let firstNameFirstLetter = this.getFirstNameFirstLetter();
    let lastNameFirstLetter = this.getLastNameFirstLetter();
    this.getInitials(firstNameFirstLetter, lastNameFirstLetter);
}

depending on if you need the variables again or just for that function.

Upvotes: 1

Related Questions