I have angular component which is displaying crypto currency prices from API. In the same service, I have an array of hard coded star rating values for each component. When I'm looping through each value from API, I also make an inside for loop to iterate through hard coded array of object literals and attach unique array value for rating for each crypto component. Older version (commented out) worked, but displayed same rating info for all crypto components. Now I commented it out and put more values in array to make it more simple. Here is the code. I don't get any errors, only undefined in console and rating component stops showing up in crypto component.
getProducts() {
return this.http.get('https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH,IOT,TRX&tsyms=USD')
.map(result => {
Object.keys(result).forEach(value => {
// add logic to have each crypto a different rating
var ratings = [{rating: 4, numOfReviews: 2}, {rating:5, numOfReviews: 3}, {rating:6, numOfReviews:1}];
for(var i = 0; i < ratings.length; i++) {
result[value]['ratingInfo'] = ratings[i].rating;
result[value]['ratingInfo'] = ratings[i].numOfReviews;
}
/* result[value]['ratingInfo'] = {
imageUrl: "http://loremflickr.com/150/150?random=1",
productName: "Product 1",
releasedDate: "May 31, 2016",
description: "Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus.",
rating: 4,
numOfReviews: 2
}*/
});
return result;
});
}
Crypto.component.ts
import { Component } from '@angular/core';
import { ProductService } from './product.service';
import { RatingComponent } from './rating.component';
@Component({
selector: 'crypto',
styleUrls: ['./app.component.css'],
template: `<h2 class="header">Crypto Price Compare</h2>
<div *ngIf="cryptos">
<div id="crypto-container" *ngFor="let crypto of objectKeys(cryptos)">
<span class="left">{{ crypto }}</span>
<span class="right">{{ cryptos[crypto].USD | currency:'USD':true }}</span>
<br />
<rating
[rating-value]="cryptos[crypto].ratingInfo.rating"
[numOfReviews]="cryptos[crypto].ratingInfo.numOfReviews">
</rating>
</div>
</div>`
})
export class CryptoComponent {
objectKeys = Object.keys;
cryptos: any;
ratings: any;
constructor(private _data: ProductService) {
}
ngOnInit() {
this._data.getProducts()
.subscribe(res => {
this.cryptos = res;
console.log(res);
});
//this.ratings = this._data.getRatings();
console.log(this.ratings);
}
onClick($event){
console.log("Clicked",$event)
}
}
You might want to change the implementation of your ProductService like this:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable()
export class ProductService {
constructor(private http: HttpClient) { }
...
getProducts() {
const ratings = [
{ rating: 4, numOfReviews: 2 },
{ rating: 5, numOfReviews: 3 },
{ rating: 6, numOfReviews: 1 },
{ rating: 7, numOfReviews: 4 }
];
return this.http.get('https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH,IOT,TRX&tsyms=USD')
.pipe(
map(
cryptos => {
const currencies = [];
let index = 0;
return Object.keys(cryptos).map((cryptoName, index) => {
return {
name: cryptoName,
price: cryptos[cryptoName].USD,
ratingInfo: { ...ratings[index] }
}
});
}
)
)
}
...
}
Doing this will result in the getProducts()
method returning an Array
of Objects that you can simply loop through in your view.
In your CryptosComponent Template, you can then do this:
<h2 class="header">Crypto Price Compare</h2>
<div *ngIf="cryptos">
<div id="crypto-container" *ngFor="let crypto of cryptos">
<span class="left">{{ crypto.name }}</span> -
<span class="right">{{ crypto.price | currency:'USD' }}</span>
<br />
<rating
[ratingValue]="crypto.ratingInfo.rating"
[numOfReviews]="crypto.ratingInfo.numOfReviews">
</rating>
</div>
</div>
NOTE:
rating-value
to ratingValue
. pipe
d through the pipe
operator. If you're using Angular 4 or 5, you'll need to do it the same way you're doing as of now, by chaining .map
to the Observable value. Here's a Sample StackBlitz for your ref.
Not sure exactly what you want to do, but this doesn't make sense.
result[value]['ratingInfo'] = ratings[i].rating;
result[value]['ratingInfo'] = ratings[i].numOfReviews;
You are setting ratingInfo and immediately overwriting it with something else. Assuming ratingInfo is an object, you probably want something like this:
result[value]['ratingInfo']['rating'] = ratings[i].rating;
result[value]['ratingInfo']['numOfReviews'] = ratings[i].numOfReviews;
Or more simply:
result[value]['ratingInfo'] = ratings[i]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.