1

I am new in Angular. I have issue in mapping. I called Web API in Angular following is the JSON object coming from the backend:

{
  "productCategoryDataModel": [
    {
      "productsCategortyName": "Electronics",
      "productsList": [
        {
          "id": 1,
          "productName": "Laptop",
          "productDescription": "Laptop Core i7",
          "productImageUrl": "fsdgdfgdfgdfgd"
        },
        {
          "id": 5,
          "productName": "IPad",
          "productDescription": "IPad",
          "productImageUrl": "hgfhgfhgf"
        }
      ]
    },
    {
      "productsCategortyName": "Grocery",
      "productsList": [
        {
          "id": 3,
          "productName": "Tomato",
          "productDescription": "Tomato",
          "productImageUrl": "dgdfgdfggdfgdf"
        },
        {
          "id": 4,
          "productName": "Onion",
          "productDescription": "Onion",
          "productImageUrl": "hgfhgfgh"
        }
      ]
    }
  ]
}

Following is the Response model class of Web API:

public class ProductsResponseModel
    {
        public List<ProductCategoryDataModel> ProductCategoryDataModel { get; set; }
    }

    public class ProductCategoryDataModel
    {
        public string? ProductsCategortyName { get; set; }
        public List<ProductsList> ProductsList { get; set; }
    }

   public class ProductsList
    {
        public int Id { get; set; }
        public string? ProductName { get; set; }
        public string? ProductDescription { get; set; }
        public string? ProductImageUrl { get; set; }
    }

I have created the following interface in angular for this JSON:

export interface IProductsResponse {
  ProductCategoryDataModel: ProductCategoryDataModel[];
}
export interface ProductCategoryDataModel
{
ProductsCategortyName: string
productsList: ProductsList[];
}
export interface ProductsList
{
ProductId: number;
ProductName: string;
ProductDescription: string;
ProductImageUrl: string;
}

Following is my Service class that calling the API:

@Injectable({
  providedIn: 'root'
})
export class ProductsListService {
  apiUrl: string = 'https://localhost:7025/api/ProductsManagement/GetAllProducts';
  constructor(private httpClient: HttpClient) { }
  getProductsGalleryData(): Observable<IProductsResponse[]> {
    return this.httpClient.get<IProductsResponse[]>(this.apiUrl);
  }

Following is my component ts file:

@Component({
  selector: 'app-products-gallery',
  templateUrl: './products-gallery.component.html',
  styleUrls: ['./products-gallery.component.css']
})
export class ProductsGalleryComponent implements OnInit {
  productsList: IProductsResponse[] | undefined;
  constructor(private _galleryProducts: ProductsListService) { }
  ngOnInit(): void {
    this._galleryProducts.getProductsGalleryData().subscribe(data => {
    this.productsList = data;
    console.log(data);
    });
  }
}

The data is displayed in the Console in the form of JSON but I have issue in the HTML file because when I use the ngFor loop for ProductsList the properties are not coming there and it gives me error so how to map the response into the interface and how to write the html to display this data?

3
  • Please add the html code to the question too since that's where your main problem is Commented Jul 28, 2022 at 12:31
  • What is missing in this question is the following: The actual json text being returned by the server. This is important so we can see why it does not match the expected typescript interface model. The HTML template products-gallery.component.html that makes use of the typescript interface model. This can show us why you might be getting an error especially when combined with the json I mentioned earlier. You need to include the error itself which includes the error message and the stack trace. You can get this from the browser development console. Also include the c# model being sent. Commented Jul 28, 2022 at 12:42
  • I did not write the HTML code because i need the HTML Commented Jul 28, 2022 at 12:57

1 Answer 1

1

The keys in the data delivered by the WebAPI are camelCase, while the Angular interfaces describe PascalCase properties. Change to camelCase in the interfaces and everything should work fine.

Also, I see your product entity has an id key, while your interface describes a ProductId key. You should change that to be id.

Another approach you can take is on your backend model, you can use JsonPropertyName() [coming from System.Text.Json.Serialization] decorator, to change the name of the keys being serialized and map them to the names you have in your Angular interfaces.

E.g.

[JsonPropertyName("ProductsList")]
public List<ProductModel> Products { get; set; }

Note: Keep in mind that .NET5+ (Asp.Net Core) does not serialize model properties PascalCase if they are named PascalCase, instead the default strategy is to turn them into camelCase keys for serialization. This can be configured.

Sign up to request clarification or add additional context in comments.

2 Comments

I followed your steps but still i am getting error in HTML page because the ProductsList does not contain the fields. Following is HTML: <div *ngFor="let category of productsList"> <h1>{{category.}}</h1> //The category does not contain any field </div> Following is the Error: ERROR Error: NG0900: Error trying to diff '[object Object]'. Only arrays and iterables are allowed at DefaultIterableDiffer.diff (core.mjs:27636:1)
Make sure your relational properties are being extracted and serialized. By default, the EFCore doesn't automatically lazy-load relational entities. Check your network tab and see what you're getting as a response from the server.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.