with *ngFor, I cannot fetch the data from my component.ts to my component.html
The same method works for one class but does not work for another class.
Here is my service class
export class FoodListService {
private url = environment.serverURL;
constructor(private http: HttpClient) {
}
//get all products from one store
getAllProducts(storeId: Number): Observable<FoodListModelServer[]> {
return this.http.get<FoodListModelServer[]>(this.url 'foodlist/' storeId);
}
Here is my component class
export class FoodListComponent implements OnInit {
foodlist: FoodListModelServer[] = [];
constructor(private foodListService: FoodListService, private router: Router, private route: ActivatedRoute) {}
ngOnInit(): void {
this.foodListService.getAllProducts(this.storeId).subscribe(food => {
this.foodlist = food;
console.log(this.foodlist);
});
}
}
Here is my component.html
<div class="col-md-8 col-lg-10 col-sm-6 card">
<li *ngFor="let foodlist of foodlist">
{{foodlist.food_name}}
</li>
</div>
Console.log(this.foodlist)
I get and object {count: 5, stores: Array(5)}
Why do I get a count included forming an object instead of just the Array?
How do I get only the array?
I have same code with the other component and it works fine. I tried everything mentioned online with no progress.
CodePudding user response:
Why do I get a count included forming an object instead of just the Array?
- it depends on the implementation of API on the backend side
How do I get only the array?
- create interface for the actual response from API and use here
this.http.get<FoodListModelServerResponse>
- then we can extract value from response via RxJs
map
operator -map(response => response.stores)
(find more info here: https://www.learnrxjs.io/learn-rxjs/operators/transformation/map) - that is it, you can subscribe to
getAllProducts
and you will get the array
import { map } from 'rxjs/operators';
export interface FoodListModelServerResponse {
count: number;
stores: FoodListModelServer[];
}
export class FoodListService {
private url = environment.serverURL;
constructor(private http: HttpClient) {
}
getAllProducts(storeId: Number): Observable<FoodListModelServer[]> {
return this.http.get<FoodListModelServerResponse >(this.url 'foodlist/' storeId)
.pipe(map(response => response.stores));
}
then you can use your implementation
ngOnInit(): void {
this.foodListService.getAllProducts(this.storeId).subscribe(food => {
this.foodlist = food;
console.log(this.foodlist);
});
}
}
CodePudding user response:
Use RxJs pluck operator to extract stores
out of response object.
Declare foodlist
variable as foodlist$: Observable<FoodListModelServer[]>
so that it is assignable to observable.
In foodService return Observable<any>
like
getAllProducts(storeId: Number): Observable<any>
import { pluck} from 'rxjs/operators';
import { Observable } from 'rxjs';
export class FoodListComponent implements OnInit {
foodlist$: Observable<FoodListModelServer[]>;
constructor(private foodListService: FoodListService, private router: Router, private route: ActivatedRoute) {}
ngOnInit(): void {
this.foodlist$ = this.foodListService.getAllProducts(this.storeId).pipe(
pluck('stores')
);
}
}
In template use Async pipe, it will take care of subscribing and unsubscribing to your foodListService.getAllProducts
<div class="col-md-8 col-lg-10 col-sm-6 card">
<li *ngFor="let foodlist of foodlist$ | async">
{{foodlist.food_name}}
</li>
</div>