1

Trying to understand why some lines of code are run before others, even though they are not written in that order.

I see in the following SO article they are suggesting Promises:

Sequential code execution in angular/ typescript

Is this recommended here, and more importantly, Why? I'm not understanding the Why from that article; it focuses more so the how.

I tried looking into js single threading, promises, observables, etc. I've also been going through a tutorial and it talks about components, modules, databinding, directives, etc but not understanding the Why.

ngOnInit() {
  this.printNames(); //Gets info from database and creates a reactive form , then prints values to console      
  console.log("NgOnInit AFTER printNames()..");
}

printNames() {
this.GetUserInfoFromDB(userID.subscribe(result => {
    this.dbt = result;
    this.createForm();
}


createForm() {
  this.profileForm = this.formbuilder.group({
    'firstName': [this.dbt.firstName],
    'lastName': [this.dbt.lastName],
  });
  console.log(this.profileForm.controls["firstName"].value);
  console.log(this.profileForm.controls["lastName"].value);
}

-

GetUserInfoFromDB(userID: string) Observable<AProfile> {
    let url = URL + '/GetUserInfo';
    let Params = new HttpParams();
    Params = Params.append('userID' userId);
    return this.http.get<AProfile>(url, {params: Params}).pipe( 
      catchError(this.handleError);
}

(Actual result) Console shows:

  • "NgOnInit AFTER printNames().."

  • "John"

  • "Smith"

(Expectation) But I expected the name to print first, then the "NgOnInit AFTER"

seesharp
  • 101
  • 10
  • 1
    Please add what `dbt` is in your `printNames` method. – SiddAjmera Feb 05 '19 at 16:35
  • 1
    Nope, I do not believe your example will reproduce what you say is happening. – Reactgular Feb 05 '19 at 16:38
  • 1
    Sounds like there's an async action based on your comment of "Gets info from database...", but that's not illustrated here. – Phix Feb 05 '19 at 16:47
  • 1
    @seesharp, the only to take account is when you make a async call. Really it's secuencial in the way that execute the functions/instructions before the call, execute the call and execute the functions/instructions after the call, but you can not expect that the call finish and Angular go on with the functions/instructions after the async call was finished – Eliseo Feb 05 '19 at 16:54
  • @Phix , I added the Observable code – seesharp Feb 05 '19 at 18:26

1 Answers1

2

this.http.get is an async call. the http request is sent before your first log then the printNames method finishes so you have your first log and then you receive the http response so the code in the subscribe method is executed (including the createForm method with the 2 logs).

Cyril
  • 256
  • 1
  • 6
  • What is the best way to ensure the async from the observable is done? Would you recommend using onCompleted as per https://stackoverflow.com/questions/45032251/angular2-how-can-i-check-if-an-observable-is-completed? Or setTimeout to ensure the values are set before I try to get one? Or just put those fields that are not from the DB into a separate hidden form? – seesharp Feb 06 '19 at 16:28
  • @seesharp I think that using onCompleted (the third argument of subscribe) is the best solution. – Cyril Feb 07 '19 at 13:02