0

I'm still figuring out angular, and I still don't understand somethings.

Let's assume I have this code:

export class test{
    testNumber: number;
    constructor(private dataService: DataServicesService) { }
    someMethod(){
        this.dataService.GetNumber().subscribe( res => this.testNumber= res)
        console.log(testNumber);
    }
    ngOnInit(){
    }
}

When I first call someMethod() and I log testNumber it logs undefined. The second time, I call it then it logs the value.

Or even if I do it on the ngOnInit():

export class test{
    testNumber: number;
    constructor(private dataService: DataServicesService) { }

    ngOnInit(){
        this.dataService.GetNumber().subscribe( res => this.testNumber= res)
        console.log(testNumber);
    }
}

I get undefined so I still don't know why if the call is before the log it doesn't work

  • The `subscribe` is asynchronous. Think of the `subscribe` as a callback when the data is available, do this. `console.log(testNumber)` will run before what's inside the subscribe block. – AliF50 Mar 05 '20 at 19:56
  • @AlifF50 so if want to get the value after what should I do? – Ricardo Sanchez Santos Mar 05 '20 at 19:59
  • The value of `testNumber`? – AliF50 Mar 05 '20 at 20:00
  • @AliF50 how do I get the value of `testNumber` without calling it two times, let's assume that after the call instead of the log I have other method and I want to pass it testNumber `otherMethod(testNumber)` or even just log the correct value and not `undefined` – Ricardo Sanchez Santos Mar 05 '20 at 20:03

1 Answers1

1

Two ways come to mind:

You can do it in an asynchronous way: (1)

import { take } from 'rxjs/operators';
......
async ngOnInit() {
  // convert the response to a promise and extract it and assign to this.testNumber
  this.testNumber = await this.dataService.GetNumber().pipe(take(1)).toPromise();
  console.log(this.testNumber); // should log the test number
}

The reactive way: (2)

this.testNumber$ = this.dataService.GetNumber();

.... // everywhere else, you have to consumer this.testNumber$ as an observable in methods like `combineLatest`, `switchMap`, `merge`, etc.

If you're comfortable with Rxjs, I would choose the 2nd (2) option. If you're comfortable with JavaScript alone, I would use the first (1) option.

AliF50
  • 16,947
  • 1
  • 21
  • 37
  • and if I consume `this.testNumber$` as an observable when I want to use its value I gotta subscribe to it? – Ricardo Sanchez Santos Mar 05 '20 at 20:10
  • Yes, you will have to subscribe to it but like I mentioned, when you have to use its value, you can put it in a `combineLatest` with another stream, `merge`, `mergeMap`, a lot of different operators. If you just need the value once and only once, I think option 1 is fine. – AliF50 Mar 05 '20 at 20:12
  • async/await isn't a good reason to ignore how asynchronous javascript works. In this precise case, using `toPromise` is a bad practice – Christian Vincenzo Traina Mar 05 '20 at 22:10