0

I can't understand the order in which my code is executed. Here I provide 2 functions and output that is received:

component:

onSubmit(model) {
    this.submitted = true;
    let newUser: User;
    newUser = this.usersService.addUser(this.model);
    this.notifyParentOnAdd.emit(newUser);
    console.log('saved Model as json ' + JSON.stringify(newUser));

  }

service:

 addUser(user: User)  {
    let savedModel: User = new User('','','',['']);
    this.httpClient.post<User>('http://localhost:8080/user/create', user).
      subscribe(res => {
        console.log(res.id);
        console.log(res.firstName);
        console.log(res.lastName);
        console.log(res.groups);
        savedModel.id = res.id;
        savedModel.firstName = res.firstName;
        savedModel.lastName = res.lastName;
        savedModel.groups = res.groups;
      });
      console.log('user-service: ' + savedModel);
      console.log(JSON.stringify(savedModel));
      return savedModel;
  }

And the output is as follows:

users.service.ts:35 user-service: [object Object]
users.service.ts:36 {"firstName":"","lastName":"","email":"","groups":[""]}
user-form.component.ts:33 saved Model as json {"firstName":"","lastName":"","email":"","groups":[""]}
users.service.ts:26 7
users.service.ts:27 test
users.service.ts:28 test
users.service.ts:29 ["WORKERS"]

It clearly shows that subscribe() method is executed at the very end that's why User object is blank.

  1. How to explain this behaviour?

  2. How to force subscribe() to execute when service method addUser() is invoked?

miki
  • 83
  • 2
  • 14
  • 1
    No. subscribe() is not executed at the very end. What is executed much later is **the callback function** passed to subscribe(). Because HTTP is **asynchronous**. If it was not, http.post would simply return the response, instead of forcing you to subscribe and pass a callback function. Just like `putBreadInToaster(); whenToasterTellsMeItIsReady(toast => eatToast(toast)); readTweetsInTheMeanTime();` – JB Nizet Dec 09 '17 at 16:32
  • Do NOT subscribe() in the service. Simply **return$$ the observable from the service: it represents an asynchronous, future result. Call subscribe() in the component. – JB Nizet Dec 09 '17 at 16:34
  • Ok i moved `subscribe()` to component but that still doesn't solve my problem. How can I be sure that I received `User` object before I start to process it further? – miki Dec 09 '17 at 16:43
  • It depends on what you want to do with the result of your service, you could apply other operators to you original Observable, perhaps make another http request or whatever. – Osman Cea Dec 09 '17 at 17:01
  • Well, put the code that needs the User **inside** the callback function that is called when the user comes back from the server. `service.addUser().subscribe(createdUser => { doSomethingWithCreatedUserHere(createdUser) })` – JB Nizet Dec 09 '17 at 17:39

0 Answers0