0

I am working on an Angular web app, with a Scala backend. I have a checkbox that should automatically tick when a condition is met. The user of the app will be prompted to enter some information on another page, and when they return it should be ticked.

I have added a println to the scala to ensure that the field is actually being updated, which is working. The .subscribe is contained within my ngOnInit(), but for some reason, it is not pulling the new data.

ngOnInit(): void {
    this.userService.loggedInUser().subscribe( u => {
        this.user = u;
        this.service.getData().subscribe( data => {
          if (data) {
            if (data.formCompleted) {
              this.formCompleted = true;
            }
          }
        })
    });
  }

I will add, that when the user clicks onto another user profile, then clicks back to the one they are editing, the box is ticked correctly. So I know the data is coming back to the app, but not when I need it.

EDIT:

So I have checked the 'Network' tab in my Inspect Element on my browser, and I can see that the data is present. I just don't understand why the if() is not being triggered. And no, it is not because of the nested subscribe(), because the user must be logged in to view this page, and that subscribe works perfectly.

LondonMassive
  • 367
  • 2
  • 5
  • 20
  • **1.** Why are the subscriptions nested when the result from first call `loggedInUser()` is not used in the second call `getData()`? Ideally nested subscriptions must be avoided. See [here](https://stackoverflow.com/a/63685990/6513921) for more info **2.** Try to write in some `console.log` statements to check what exactly is triggered. – ruth Jul 15 '21 at 13:31
  • If the Observables are asynchronous then it's very like that you'll need to trigger change detection manually. https://stackoverflow.com/questions/34827334/triggering-change-detection-manually-in-angular – martin Jul 15 '21 at 13:34
  • Hi, thanks for replying quickly. I have just started working at this new company, I have just finished uni. I am the first junior programmer on the team, and I haven't programmed this, I have just been tasked with fixing the bug. Also, I added some ``console.log()`` to see what is being triggered. Inside the second ``.subscribe``, if I write ``console.log("TEST: " + data.formCompleted)``, I only get ``TEST: ``. But if i navigate to another user, then come back, I get ``TEST: true`` – LondonMassive Jul 15 '21 at 13:35
  • But, I need the box to be ticked without the user having to switch user – LondonMassive Jul 15 '21 at 13:36
  • Because the inner subscribe only triggers when the outer one does (very bad practice btw) - it is possible the inner subscription call was already triggered, so you’re basically missing the inner one. Hard to tell without knowing what getData() does. Anyway, don’t use nested subscriptions.. bad idea. – MikeOne Jul 15 '21 at 14:00
  • Ok, I have implemented that change, and no difference. The inner one was always getting called, I used some ``console.log()`` and secondly the outer one just ensures that the user is logged in, which they would have to be anyway to access the page I am having troubles with. – LondonMassive Jul 15 '21 at 14:04
  • Doing a *small* example of this in stackblitz could make it easier for us to help. – DeborahK Jul 15 '21 at 17:10

1 Answers1

0

It sounds like a more declarative, reactive approach may work better for your scenario. Something like this (not tested since I don't have your methods).

user$ = this.userService.loggedInUser();

data$ = this.user$.pipe(
           switchMap(user => this.service.getData()),
           tap(data => {
                 if (data.formCompleted) {
                    this.formCompleted = true;
                 }
           })
        );

ngOnInit(): void {
   this.sub = this.data$.subscribe();
}

ngOnDestroy(): void {
   this.sub.unsubscribe();
}

For more information on this technique, check out the first talk here: https://www.youtube.com/watch?v=iSsch65n8Yw

DeborahK
  • 57,520
  • 12
  • 104
  • 129
  • Hi, thanks for the suggestion. I have implemented this, and unfortunately, I am getting the same result. I have checked the developer tools for my browser, and the network request is showing that the correct data is being returned to the app, but for some reason, the assignment of this data to the variable is not working. I think this has something to do with it being asynchronous, do you agree? If so, do you have a suggestion to deal with that? Thanks – LondonMassive Jul 16 '21 at 09:50
  • The entire purpose of an Observable is to handle asynchronous data. (The relevant portion of that above linked youtube video is only about 25 minutes. It would definitely be worth your time.) The declarative, reactive approach shown above is often the best way to handle data that is being updated. (Except normally devs use the async pipe, not a subscribe.) If you could do a stackblitz that demonstrates the issue, I'd be happy to help you figure out what's wrong. – DeborahK Jul 16 '21 at 15:16
  • As specified in the related question here: https://stackoverflow.com/questions/68408836/angular-subscribe-not-updating-data I put together a working Stackblitz that hopefully is close to what you are trying to accomplish. If not, feel free to fork the stackblitz and change it as necessary to illustrate your issue. https://stackblitz.com/edit/angular-posts-behavior-subject-procedural-vs-declarative-zsbs9e – DeborahK Jul 16 '21 at 19:41