Home > Software engineering >  Getting data from api in angular but in component it is showing as undefined
Getting data from api in angular but in component it is showing as undefined

Time:09-27

I have service which returns an observable which does an http request to my server and gets the data. I want to use this data but I am getting data as null later after completing pageload in network tab able to see data.

Service

getUserData(userId : string): Observable<any>{
    const headers = new Headers({ 'Content-Type': 'application/json' });

    return this.http.get<any[]>("user/get", headers)
  }

component(userconfigs.ts)

getUserInfo() {
    this.service.getUserData(userId).subscribe((response) => {
      if (response != null) {
        this.myDetails.Name = response[0].name;
        this.myDetails.Age = response[1].age;
                .
                .
        return this.myDetails

      }

    });
  }
   = ;

We are using getUserInfo() in multiple components like app component, homepage, footerpage. data is shown as undefined

homepage

ngoninit(){
//calling userconfig.ts getUserInfo() method here to get data
this.userDetails = this._userconfigs.getUserInfo();
}

CodePudding user response:

First, you are trying to use async callbacks (observables) as synchronous.

this.userDetails = this._userConfigs.getUserInfo()

the getUserInfoInfo does not return anything. it merely calls the service.

this is why userDetails is null. because the method you are calling doesn't return anything.

secondly, you must wait for the asychronous call to complete

update your getUserInfo to only update the component property once the observable is complete.

getUserInfo() {
    this.service.getUserData(userId).subscribe((response) => {
      if (response != null) {
        this.myDetails.Name = response[0].name;
        this.myDetails.Age = response[1].age;
                .
                .
        // Only once the subscription is complete, can you access the data from the observabe. 
        // so here, you should update your component property
        this.userDetails  = response;

      }

    });
  }

alternatively, if you want your method to return an observable, you would need to change your code as follows

// return either UserDetail object or undefined if no data returned
getUserInfo(): Observable< UserDetail | undefined > {
    // return the observable from the service
    return this.service.getUserData(userId).pipe(
     map( (response) => {
      // gracefully handle no data being returned
      if( !response) {
         return undefined;
      }
      // now that we know data exists we can process it.
      return {
         Name: response[0].name,
         age: response[0].age,
         .
         .
      };
    })
  )
}

then modify your ngoninit to call this method and wait for the response to process

ngoninit(){
   // call method to & udpate component.userDetail upon response
   this._userconfigs.getUserInfo().pipe(
     // You only need one response as you aren't looking for a stream of data
     take(1)
   ).subcribe( {
      next: (response: UserData Undefined) => {
         // Only after the observable has completed do you have access to the data.
         // so you can now update the component property
         // Remembering that this value can be either an object or undefined
         this.userDetail = response;
      }
   });
}

CodePudding user response:

Use BehaviourSubject (https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject)

Service

myDetails$ = new BehaviorSubject([]);

getUserInfo(){
   this.service.getUserData(userId).subscribe((response)=>{
     if(response != null){
        this.myDetails$.next(response);
    }
    
  });
}

Component

this.service.myDetails$.subscribe((response) => {
      this.userDetails.Name = response[0].name;
      this.userDetails.Age = response[1].age;

})
  • Related