0
votes

I have a JSON file, with a list of for sale properties. I am trying to use *NgFor to loop through the data to create a list.

Firstly I am still an amateur with angular and app development so there is a possibility I may have misinterpreted documentation etc

I have tried looping through different paths

*NgFor="let post of posts.properties"
*NgFor="let post of posts.properties.property"

and still getting various errors.

My understanding, is I have to cast the observable to an array of properties. And then bind it to the html. (Which I believe I have done as properties is of type array?

json

{
    "properties": {
        "property": [
            {
                "propertyID": "101552000007",
                "branchID": "1",
                "clientName": "A Demo",
                "branchName": "Brackley",
                "department": "Sales",
                "referenceNumber": "10006",
                "addressName": "",
                "addressNumber": "87",
                "addressStreet": "Hackney Road",

properties.interface.ts

export interface IProperties {
    addressStreet: string;
    addressNumber: number;
}

For-sale.service.ts

import { IProperties } from './../properties.interface';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';



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

  constructor(private http: HttpClient) {

  }


  getProperties(): Observable<IProperties[]> {
    return this.http.get<IProperties[]>('/assets/data/jupix.json');

  }

}

for-sale.page.ts

import { ForSaleService } from './for-sale.service';
import { Component, OnInit } from '@angular/core';


@Component({
  selector: 'app-for-sale',
  templateUrl: './for-sale.page.html',
  styleUrls: ['./for-sale.page.scss'],
  providers: [ForSaleService]
})
export class ForSalePage implements OnInit {

  public properties = [];

  constructor(private saleService: ForSaleService) { }

  ngOnInit() {

    this.onGetProperties();

  }



  onGetProperties() {
    this.saleService.getProperties()
      .subscribe(response => {
        console.log(response);
        this.properties = response;
      });
  }
}

html

<ion-content>
  <ion-list *ngFor="let property of properties">
    <ion-card>

      <ion-card-header>{{ property.addressNumber }}</ion-card-header>
      <ion-card-content>
        <p>
          <ion-icon name="person" color="primary"></ion-icon>
        </p>
      </ion-card-content>
    </ion-card>
  </ion-list>
</ion-content>

What I don't understand is, let property of properties is bound to the array of properties?

EDIT: After trying a few suggestions, there appears to be a pattern emerging to the errors in the console log? It appears to see child elements as undefined as these are the ones throwing errors?

So i changed the variable completely to propertiesList to make it easier to read. A really weird thing is occuring now. So we have *ngFor="let property of propertiesList.properties.property"

Then for the card image <img src="{{ property.images.image[0].__text }}" alt=""> This works as intended, the image shows. However in the console log Cannot read property '__text' of undefined and the original " Cannot read property 'property' of undefined

So i continued adding other elements in the html

<ion-card-header>{{ property.addressNumber }} {{ property.addressStreet }} {{ property.addressPostcode }}</ion-card-header>

These work fine, no errors, data displays. Now this is where it gets weird.

<p>{{ property.propertyFeature1 }} {{ property.floorplans.floorplan._modified }}</p>

I now add this, and Cannot read property '__text' of undefined vanishes! and is instead replaced with Cannot read property '__modified' of undefined along with the original Cannot read property 'property' of undefined

In visual studio code, the only error im getting is Identifier 'properties' is not defined. 'Array' does not contain such a member

3
Please Check this *ngIf="properties.properties.property?.length > 0" before the loop - Sandy Sanap

3 Answers

1
votes

From the docs:

An object is iterable if it defines its iteration behavior, such as what values are looped over in a for...of construct. Some built-in types, such as Array or Map, have a default iteration behavior, while other types (such as Object) do not.

Change the ngFor to the following:

<ion-list *ngFor="let property of properties.property">

Then you will be able to iterate since it is an array.

1
votes

You can try this

Check *ngIf="properties.properties.property?.length > 0" condition before the loop so it will check whether array or object is empty or not.

 <ion-content *ngIf="properties.properties.property?.length > 0">
      <ion-list *ngFor="let property of properties.properties.property">
       <ion-card>

        <ion-card-header>{{ property.addressNumber }}</ion-card-header>
        <ion-card-content>
          <p>
           <ion-icon name="person" color="primary"></ion-icon>
          </p>
        </ion-card-content>
      </ion-card>
   </ion-list>
  </ion-content>

so you will not get any error in console like Cannot read property 'property' of undefined

I hope this will be useful.

0
votes

According to me, the get call cannot correctly map your data to your properties defined in your Interface. As the mapping is not correct is won't be a correct array that can be looped over.

based on what you provided with all the variables, you need to loop over it via:

<ion-list *ngFor="let property of properties.properties.property">

properties as your result array, then properties as a property of the json + property as an actually array with data... don't even know if this two identical identifiers are going to work