Home > Software design >  Response.forEach is not a function Typescript
Response.forEach is not a function Typescript

Time:07-06

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:

Swagger response

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}`);
  });
}
  • Related