Code of my product-list component is as follows:
import {ChangeDetectorRef, Component} from '@angular/core';
import {ProductsListService} from './products-list.service';
@Component({
selector: 'app-products-list',
templateUrl: './products-list.component.html',
styleUrls: ['./products-list.component.css']
})
export class ProductsListComponent {
rerender = false;
products;
constructor(private service: ProductsListService, private cdRef: ChangeDetectorRef) {
this.products = service.getProducts();
}
getProductsAgain(query: string): void {
this.products = this.service.getProducts(query);
console.log(this.products);
this.doRerender();
}
// tslint:disable-next-line:typedef
doRerender() {
this.rerender = true;
this.cdRef.detectChanges();
this.rerender = false;
}
}
and html looks like this:
<ng-container *ngIf="!rerender">
<ul>
<li *ngFor="let product of products">
<img src="{{product.picture}}" height="150px">
<p>{{product.title}}</p>
<div>
<p>{{"ENERC_KCAL: "+product.nutrients._ENERC_KCAL}}</p>
<p>{{"PROCNT: "+product.nutrients._PROCNT}}</p>
<p>{{"FAT: "+product.nutrients._FAT}}</p>
<p>{{"CHOCDF: "+product.nutrients._CHOCDF}}</p>
<p>{{"FIBTG: "+product.nutrients._FIBTG}}</p>
</div>
</li>
</ul>
</ng-container>
also product-list.service looks like this:
import {Injectable, Optional} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {ResponseDTO} from './ResponseDTO';
import {NutrientsDTO} from './NutrientsDTO';
@Injectable({
providedIn: 'root'
})
export class ProductsListService {
constructor(private http: HttpClient) {
}
public getProducts(q?: string): Array<ResponseDTO> {
const query = (q === undefined) || (q == null) || (q === '') || (q === ' ') ? 'orange' : q;
const url = 'https://edamam-food-and-grocery-database.p.rapidapi.com/parser?ingr=' + query;
const httpHeaders = new HttpHeaders({
'content-type': 'application/json',
'x-rapidapi-key': '9f95da4cd3mshd0fbea030c7c8e3p16d06bjsn503efa8f187f',
'x-rapidapi-host': 'edamam-food-and-grocery-database.p.rapidapi.com'
});
const arr: Array<any> = [];
const res: Array<ResponseDTO> = [];
this.http.get(url, {headers: httpHeaders, observe: 'body', responseType: 'json'}).subscribe(data => {
const obj = JSON.parse(JSON.stringify(data));
arr.push(obj.hints);
for (const ar of arr) {
const nutrients: NutrientsDTO = new NutrientsDTO();
for (const a of ar) {
// tslint:disable-next-line:forin
for (const nutrient in a.food.nutrients) {
if (a.food.nutrients.hasOwnProperty(nutrient)) {
if (nutrient === 'ENERC_KCAL') {
nutrients.ENERC_KCAL = Math.round((a.food.nutrients[nutrient] + Number.EPSILON) * 100) / 100;
} else if (nutrient === 'PROCNT') {
nutrients.PROCNT = Math.round((a.food.nutrients[nutrient] + Number.EPSILON) * 100) / 100;
} else if (nutrient === 'FAT') {
nutrients.FAT = Math.round((a.food.nutrients[nutrient] + Number.EPSILON) * 100) / 100;
} else if (nutrient === 'CHOCDF') {
nutrients.CHOCDF = Math.round((a.food.nutrients[nutrient] + Number.EPSILON) * 100) / 100;
} else if (nutrient === 'FIBTG') {
nutrients.FIBTG = Math.round((a.food.nutrients[nutrient] + Number.EPSILON) * 100) / 100;
} else {
console.log('not found!');
}
}
}
const noImgUrl = 'https://st4.depositphotos.com/14953852/24787/v/600/depositphotos_247872612-stock-illustration-no-image-available-icon-vector.jpg';
const imgSrc = a.food.image == null ? noImgUrl : a.food.image;
const response: ResponseDTO = new ResponseDTO(imgSrc, a.food.category, a.food.label, nutrients);
res.push(response);
}
}
}
);
return res;
}
}
I am calling product-list method getProductsAgain by different component search-bar, which simply goes back to the service and calls API again with given parameter. The call is successful and it also assigns value to product variable of ProductsListComponent, but page does not refresh or re-render html. What should I do? or what am I doing wrong?
UPDATE #1:
Still have same problem, I tried all methods like trackBy, [...arrayOfResults], returned Subscription or Observable in component and got result in there, inspected result with setTimeout(()=>{console.log(products)},5000); to see if API request really assigns new values to products variable (and it does!). I even tried to force re-render with ChangeDetectorRef.detectChanges() but no success.
So with API request is nothing wrong, but for some reason angular does not see that I update with API request products variable and its stuck on initial results (results in service.getProducts()). What am I doing so wrong?
ngOnInit()instead.service.getProducts()looks like. It might be returning the wrong thing.Array<ResponseDTO>array list of object where I map JSON response values to object variables. I will update question with more infoconsole.log(this.products)after API call i do get all necessary data?