Alamzaib Farooq
Alamzaib Farooq

Reputation: 317

Unable to assign data to object when outside of subscribe method scope

I am able to assign data to this.basicdata when I am in subscribe method but when I console.log it outside the scubscribe it gives undefined.

Here is my typescript code:

id: string;
    substance: string;
    subscription: Subscription;
    basicData: IBasicData;
  constructor(private route: ActivatedRoute,
              private _sharedService: SharedService,
              public packAndPriceService: PacksAndPricesService) { }

ngOnInit(): void {
  this.route.paramMap.subscribe((params: ParamMap) => {
      this.id = params.get('id');
      this.substance = params.get('selectedType');
  });
  this.subscription = 
  this.packAndPriceService.searchDrugByBasicDataId(this.id).subscribe((data: IBasicData) => {
      this.basicData = data;
  });
  console.log(this.basicData);
  }

Here is the service code:

 searchDrugByBasicDataId(searchString: string): Observable<IBasicData> {
        return this._httpClient.get<IBasicData>(this.baseUrl+'v1/drug/search-drug-id/'+searchString);
    }

If I do this it's giving me error that undefined property drugName

this.subscription = this.packAndPriceService.searchDrugByBasicDataId(this.id).subscribe((data: IBasicData) => {
              this.basicData = data;
          });
          const selectionData = new SearchSelectedItem();
          selectionData.selectedType = this.selectedType.charAt(0).toUpperCase() + this.selectedType.slice(1);
          selectionData.name = this.basicData.drugName;
          selectionData.id = this.id;
          this._sharedService.emitChange(selectionData);

If I move the code inside subscribe then it works.

Upvotes: 0

Views: 158

Answers (2)

Andres2142
Andres2142

Reputation: 2897

Take a look at the following example:

let name: string | undefined = undefined;
const mockHttpRequest$ = of('someHTTPResponse').pipe(delay(100));

mockHttpRequest$.subscribe(() => {
  name = 'Dave';
  console.log('I will be executed Second: ', name)
});

console.log('I will be executed First: ', name);

The output will be:

//I will be executed First: undefined
//I will be executed Second:: Dave

When you subscribe to an observable, that code running is asynchronous, meaning, it will run sometime in the future, the outer console.log runs first, because is synchronous.

The behavior you are having with your code is 100% correct, is expected. That's how observables work. If you need to do something with the observable data before subscribing, you can pipe it and apply all the necessary rxjs operators. If you need to do something with this.basicData, you need to handle it while you are subscribing. I could suggest ways of handling your code but, I don't know exactly (based on your code) when and how are you going to use this.basicData

If you need to show it on your template HTML, then store the observable result, and let the HTML handle it using the async pipe, with that, you don't handle the subscription:

basicData$!: Observable<IBasicData>

ngOnInit(): void {
  this.basicData$ = this.searchDrugByBasicDataId(this.id);
}
<ng-container *ngIf={ basicData$ | async as myData }>
 <div>
   <p>myData.someProperty1</p>
   <p>myData.someProperty2</p>
   ...
 </div>
</ng-container>

You can learn more about observables here

Upvotes: 2

Exception
Exception

Reputation: 592

In .ts file

     id: string;
    substance: string;
    subscription: Subscription;
    basicData: IBasicData;
  constructor(private route: ActivatedRoute,
              private _sharedService: SharedService,
              public packAndPriceService: PacksAndPricesService) { }

ngOnInit(): void {
  this.route.paramMap.subscribe((params: ParamMap) => {
      this.id = params.get('id');
      this.substance = params.get('selectedType');
  });
  this.getSearchDrugByBasicDataId();
  console.log(this.basicData);
  }
  async getSearchDrugByBasicDataId() {
    this.subscription =await this.packAndPriceService.searchDrugByBasicDataId(this.id).subscribe((data: IBasicData) => {
      this.basicData = data;
    });
    console.log(this.basicData)
  }

Upvotes: 0

Related Questions