Home > Enterprise >  Angular project connected to ASP.NET Web API does not show data in the browser
Angular project connected to ASP.NET Web API does not show data in the browser

Time:06-21

I am trying to get some data from an ASP.NET 4.7 Web API, database first, using Entity Framework 5 and trying to use the data into an Angular v13.3.11 project, and showing that data in the browser.

I'm a beginner programmer and I appreciate your help in advance.

Both projects are local and are used for learning purposes.

Motorcycle class:

namespace TestUsersCopyApi3.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Motorcycle
    {
        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; }
        public virtual ICollection<Cart> Carts { get; set; }
        public virtual Category Category { get; set; }
        public virtual ICollection<OrderDetail> OrderDetails { get; set; }
        public virtual ICollection<Dealer> Dealers { get; set; }
    }
}

Brand class:

namespace TestUsersCopyApi3.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Brand
    {
        public Brand()
        {
            this.Motorcycles = new HashSet<Motorcycle>();
            this.Categories = new HashSet<Category>();
            this.Dealers = new HashSet<Dealer>();
        }
    
        public int BrandId { get; set; }
        public string Name { get; set; }
        public byte[] Image { get; set; }
    
        public virtual ICollection<Motorcycle> Motorcycles { get; set; }
        public virtual ICollection<Category> Categories { get; set; }
        public virtual ICollection<Dealer> Dealers { get; set; }
    }
}

MotorTestDTO class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TestUsersCopyApi3.Models
{
    public class MotorTestDTO
    {
        public string Model { get; set; }
        public double Price { get; set; }
        public byte[] Image { get; set; }
        public string BrandForMotor { get; set; }
    }
}

MotorTestController:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Http;
using TestUsersCopyApi3.Models;
using System.Web.Http.Cors;

namespace TestUsersCopyApi3.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class MotorTestController : ApiController
    {
        private NavEcommerceDBfirstEntities db = new NavEcommerceDBfirstEntities();

        // GET: MotorTest
        public IQueryable<MotorTestDTO> Get()
        {
            var allMotorcycles = db.Motorcycles
                .Select(m => new MotorTestDTO
                {
                    Model = m.Model,
                    Price = m.Price,
                    Image = m.Image,
                    BrandForMotor = m.Brand.Name
                });
            return allMotorcycles;
        }
    }
}

On the Angular side:

motor-test.model:

import { Byte } from "@angular/compiler/src/util";

export interface MotorTest{
    model: string;
    price: string;
    image: Byte[];
    brandForMotor: string;
    }

motortest.service.ts:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { MotorTest } from '../Model/motor-test.model';

@Injectable({
  providedIn: 'root'
})
export class MotortestService {

baseUrl = 'https://localhost:*****/api/MotorTest';
constructor(private http: HttpClient) { }

getAllMotorsTest(): Observable<MotorTest[]>{
return this.http.get<MotorTest[]>(this.baseUrl);
}
}

app.component.ts:

import { Component, OnInit } from '@angular/core';
import { MotortestService } from './Service/motortest.service';
import { MotorTest } from './Model/motor-test.model';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'AngularUI';
allModelsForMotorTest: MotorTest[] = [];

  constructor(private motortestService: MotortestService) {}

ngOnInit(): void{
  this.allMotorsTest();
}

allMotorsTest(){
  this.motortestService.getAllMotorsTest().subscribe(
    response => {
      this.allModelsForMotorTest = response;
      console.log(response);
    }
  )
}
}

app.component.html:

<h4>
    {{title}}</h4>

<div *ngFor="let item of allModelsForMotorTest">
    <span>{{item.model}}</span>
    <span>{{item.price}}</span>
    <span>{{item.image}}</span>
    <span>{{item.brandForMotor}}</span>
</div>

The question

How come the output is a blank page in the browser but I can log the data to the console ?

However my main question is specifically about the variable BrandForMotor in the API and brandForMotor in the Angular project side which are pointing to the same thing, When I remove these variable I get the output both to the browser and the DevTools Console pane with no problem but as soon as I consider adding BrandForMotor nothing appears to the output browser ?

Is the query that I'm making via allMotorcycles variable in the MotorTestController ok ?

Here are some screenshots after running the API and serving the Angular project:

Swagger:

Swagger

DevTools Console Showing the Data, Sent From the API

Blink Browser Page, Angular Output

Thank you in advance.

CodePudding user response:

If you look closer at the response returned, those properties are in PascalCase which believes that the item value will not able to be binded to the Typescript interface/class.

Two approaches can be used:

Approach 1:

Modify the Typescript interface properties to match with the returned response by changing the properties to PascalCase.

export interface MotorTest {
  Model: string;
  Price: string;
  Image: Byte[];
  BrandForMotor: string;
}
<div *ngFor="let item of allModelsForMotorTest">
    <span>{{item.Model}}</span>
    <span>{{item.Price}}</span>
    <span>{{item.Image}}</span>
    <span>{{item.BrandForMotor}}</span>
</div>

Approach 2:

Configure the WebApi to return the response as camelCase.

Reference: Web API 2: how to return JSON with camelCased property names, on objects and their sub-objects

  • Related