I'm new in programming specially in angular and I'd appreciate it if someone help me with my code, please.
I'm trying to get some images from a web api in angular project.
- ASP.NET Framework Web API 4.7
- Angular CLI: 13.3.7
- Angular: 13.3.11
Web API side:
Controller:
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class HomeController : ApiController
{
private NavEcommerceDBfirstEntities db = new NavEcommerceDBfirstEntities();
public HomeModel Get()
{
var streetBikes = db.Motorcycles
.Where(m => m.Category.MotoCategory == "Street")
.Select(m => new MotorcycleImgDTO
{
Image = m.Image
});
var sportBikes = db.Motorcycles
.Where(m => m.Category.MotoCategory == "Sport")
.Select(m => new MotorcycleImgDTO
{
Image = m.Image
});
var adventureBikes = db.Motorcycles
.Where(m => m.Category.MotoCategory == "Adventure")
.Select(m => new MotorcycleImgDTO
{
Image = m.Image
});
var scooterBikes = db.Motorcycles
.Where(m => m.Category.MotoCategory == "Scooter")
.Select(m => new MotorcycleImgDTO
{
Image = m.Image
});
var homeModel = new HomeModel
{
SportBikes = sportBikes,
StreetBikes = streetBikes,
AdventureBikes = adventureBikes,
ScooterBikes = scooterBikes
};
return homeModel;
}
}
Models:
HomeModel class:
public class HomeModel
{
public IEnumerable<MotorcycleImgDTO> StreetBikes { get; set; }
public IEnumerable<MotorcycleImgDTO> SportBikes { get; set; }
public IEnumerable<MotorcycleImgDTO> AdventureBikes { get; set; }
public IEnumerable<MotorcycleImgDTO> ScooterBikes { get; set; }
}
Motorcycle class:
//Database First Approach and Created by ADO.NET
public partial class Motorcycle
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Motorcycle()
{
this.Carts = new HashSet<Cart>();
this.OrderDetails = new HashSet<OrderDetail>();
this.Dealers = new HashSet<Dealer>();
}
public int MotorcycleId { get; set; }
public string Model { get; set; }
public double Price { get; set; }
public Nullable<int> BrandId { get; set; }
public byte[] Image { get; set; }
public Nullable<int> CategoryId { get; set; }
public virtual Brand Brand { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Cart> Carts { get; set; }
public virtual Category Category { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Dealer> Dealers { get; set; }
}
DTO class:
public class MotorcycleImgDTO
{
public byte[] Image { get; set; }
}
Angular Side:
Model:
home-categorised-bikes.model.ts:
export interface FromDTOImgs{
image: Byte[];
}
export interface HomeModel{
sportBikes: FromDTOImgs[];
streetBikes: FromDTOImgs[];
adventureBikes: FromDTOImgs[];
scooterBikes: FromDTOImgs[];
}
Service:
home-categorised-bikes.service.ts:
@Injectable({
providedIn: 'root'
})
export class HomeCategorisedBikesService {
imageUrl = 'https://localhost:44377/api/Home';
constructor(private http: HttpClient) { }
getImg(): Observable<HomeModel[]> {
return this.http.get<HomeModel[]>(this.imageUrl);
}
}
app.component.ts:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'angular-UI';
constructor(private homeCategorisedBikesService: HomeCategorisedBikesService){}
ngOnInit(): void {
this.getAllBikesImgs();
}
getAllBikesImgs(){
this.homeCategorisedBikesService.getImg().subscribe(
Response => {
this.onHomeBikesImgsResponse(Response);
console.log(Response);
}
)
}
public bikesImgs: string[] = [];
private onHomeBikesImgsResponse(Response: HomeModel[]): void {
Response.forEach((img: HomeModel) => {
this.bikesImgs.push(`data:image/png;base64,${img.sportBikes}`);
this.bikesImgs.push(`data:image/png;base64,${img.streetBikes}`);
this.bikesImgs.push(`data:image/png;base64,${img.adventureBikes}`);
this.bikesImgs.push(`data:image/png;base64,${img.scooterBikes}`);
});
}
}
app.component.html:
<div >
<h4>{{title}}</h4>
<div *ngFor="let bikeImg of bikesImgs">
<img [src]="bikeImg">
</div>
Swagger:
Error:
Response.forEach is not a function at AppComponent.onHomeBikesImgsResponse (app.component.ts)
Thank you in advance.
CodePudding user response:
As you can see in your own swagger screenshot, your response in not an array, it's a list of objects streetBikes
, sportBikes
.... Each of those objects are list of arrays.
To loop through each property and to create one single array of all bike images, you need something like this:
private onHomeBikesImgsResponse(Response: HomeModel): void {
for (const prop in Response) {
Response[prop].forEach((item: FromDTOImgs) => {
this.bikesImgs.push(`data:image/png;base64,${item.image}`);
});
}
CodePudding user response:
Your API returns response
with HomeModel
type, but not HomeModel
array.
home-categorised-bikes.service.ts:
export class HomeCategorisedBikesService {
imageUrl = 'https://localhost:44377/api/Home';
constructor(private http: HttpClient) { }
getImg(): Observable<HomeModel> {
return this.http.get<HomeModel>(this.imageUrl);
}
}
app.component.ts:
private onHomeBikesImgsResponse(Response: HomeModel): void {
Response.sportBikes.forEach((img: FromDTOImgs) => {
this.bikesImgs.push(`data:image/png;base64,${img.image}`);
});
Response.streetBikes.forEach((img: FromDTOImgs) => {
this.bikesImgs.push(`data:image/png;base64,${img.image}`);
});
Response.adventureBikes.forEach((img: FromDTOImgs) => {
this.bikesImgs.push(`data:image/png;base64,${img.image}`);
});
Response.scooterBikes.forEach((img: FromDTOImgs) => {
this.bikesImgs.push(`data:image/png;base64,${img.image}`);
});
}