Home > Back-end >  Error with BehaviourSubject to the component from service return empty array
Error with BehaviourSubject to the component from service return empty array

Time:03-07

i'm new with rxJs i have problem to pass data to component from service? the response give to me an empty array only in the component`

THIS IS THE SERVICE

todo = new Subject<Excercise[]>();
  excerciseList$ = this._todo.asObservable();

  ngOnInit(): void {
    console.log(this.excerciseList$);
  }

  getExcercise(): Observable<Excercise[]> {
    var header = {
      headers: new HttpHeaders().set(
        'Authorization',
        'Token 46800b8343b85a2558a50dc5f5e661c274ecd340'
      ),
    };
    this.httpClient
      .get<Excercise[]>('https://wger.de/api/v2/exerciseimage/', header)
      .subscribe((response: any) => {
        this.excerciseList$ = response['results'];
        console.log('[Response]', response['results']);
        console.log('[Response List]', this.excerciseList$);
      });
    return this.excerciseList$;
  }

IN THE COMPONENT

export class TodoListComponent implements OnInit {
  excercises$: Observable<Excercise[]> = this.excerciseService.getExcercise();

  constructor(private excerciseService: ExcerciseListServiceService) {}
   
  ngOnInit(): void {
    console.log(
      this.excerciseService.excerciseList$.subscribe((res) => console.log(res))
    );
  }

CodePudding user response:

Don't "de-Observable" anything until you absolutely have to. Most often, you can maintain an Observable all the way to the template with the async pipe:

// Service
getExcercise(): Observable<Excercise[]> {
  const headers = {
    headers: new HttpHeaders().set(
      'Authorization',
      'Token 46800b8343b85a2558a50dc5f5e661c274ecd340'
    ),
  };
  return this.httpClient.get<Excercise[]>('https://wger.de/api/v2/exerciseimage/', headers);
}

// Component
this.excercise$ = this.excerciseService.getExcercise();

And in the template where you display the data:

<div *ngFor="let excercise of excercise$ | async">
  {{ excercise.name }}
</div>

CodePudding user response:

Why can't you directly call the getExcersice() method in the ngOnInit() like this,

this.excerciseService.getExcercise().then(result => {
console.log(result);
});

Since the Http method call already returns an observable you don't need to declar a new subject in the service class. Also on the service file do the following

return this.httpClient
      .get<Excercise[]>('https://wger.de/api/v2/exerciseimage/', header);

This returns an observable which you can use at the component side as shown above.

Or else if you are using the results to load a list in the HTML,

you can directly call the method from the OnInit method and use it as below,

excercises$ = this.excerciseService.getExcercise();

and use the async pipe to render excercises$ results in the HTML.

Hope this makes sense.

  • Related