typescriptnativescriptngfornativescript-angularng-container

Issues with *ngFor and GridLayout in Nativescript


I have a problem with the grid layout. My code is this one:

    <GridLayout padding="10%"columns="auto, auto, auto, auto, auto, auto, auto" rows="*">
      <ng-container *ngFor="let item of items">
        <label [text]="item.codice" col="0",[row]="{{item.row}}"fontSize="24px"></label>
        <label [text]="item.prodotto" col="1",[row]="{{item.row}}"fontSize="24px"></label>
        <label [text]="item.lottoData" col="2",[row]="{{item.row}}"fontSize="24px"></label>
        <label [text]="item.codiceCont" col="3",[row]="{{item.row}}"fontSize="24px"></label>
        <label [text]="item.qtyUntPri" col="4",[row]="{{item.row}}"fontSize="24px"></label>
        <label [text]="item.studioCieco" col="5",[row]="{{item.row}}"fontSize="24px"></label>
        <label [text]="item.qty" col="6",[row]="{{item.row}}"fontSize="24px"></label>
      </ng-container>
    </GridLayout> 

I'm expecting to see those columns and a row for each item, but I have something like you can see in the image below:

enter image description here

If you need to see the typescript

  ngOnInit(): void {
    var usefulData = this.data["param"]["response"];
    var firstTable = usefulData[0];
    var secondTable = usefulData[1];
    this.studyCode = firstTable[0]["StudyCode"];
    this.nameFile = firstTable[0]["NameFile"];
    var row = 1;
    for (var i in secondTable){
      if(secondTable[i] != undefined){
        this.items.push({
        codice:secondTable[i]["Codice"],
        prodotto:secondTable[i]["Product"],
        lottoData:secondTable[i]["LottoData"],
        codiceCont:secondTable[i]["CodiceCont"],
        qtyUntPri:secondTable[i]["QtyUntPri"],
        studioCieco:secondTable[i]["StudioCieco"],
        qty:secondTable[i]["Qty"],
        row:row
      });
      row+=1;
      }
    }
  }

Solution

  • You declared the GridLayout with rows="*", which means that you have only one row:

    <GridLayout padding="10%"columns="auto, auto, auto, auto, auto, auto, auto" rows="*">
    

    This is why you're seeing the overlapping condensed text in the screenshot you provided.

    Reminder: The rows and columns of {N} GridLayout take either:

    To fix this, you need to set the rows property to reflect the number of rows that should be available on your GridLayout. For example, if you have an item with [row]="{{item.row}}", and the maximum item.row = 5, then your GridLayout should be declared like below:

    <GridLayout
        padding="10%"
        columns="auto, auto, auto, auto, auto, auto, auto"
        rows="auto, auto, auto, auto, auto" <-- note the 5 rows
    >
        <!-- child elements ... -->
    </GridLayout>
    

    In your example it looks like you have to calculate the number of rows and bind this to the rows property of the Gridlayout, like so:

        public gridRows: string;
    
    
        ngOnInit(): void {
            var usefulData = this.data['param']['response'];
            var firstTable = usefulData[0];
            var secondTable = usefulData[1];
            this.studyCode = firstTable[0]['StudyCode'];
            this.nameFile = firstTable[0]['NameFile'];
            var row = 1;
            for (var i in secondTable) {
                if (secondTable[i] != undefined) {
                    this.items.push({
                        codice: secondTable[i]['Codice'],
                        prodotto: secondTable[i]['Product'],
                        lottoData: secondTable[i]['LottoData'],
                        codiceCont: secondTable[i]['CodiceCont'],
                        qtyUntPri: secondTable[i]['QtyUntPri'],
                        studioCieco: secondTable[i]['StudioCieco'],
                        qty: secondTable[i]['Qty'],
                        row: row,
                    });
                    row += 1;
                }
            }
    
            const rowsCount = row;
            this.gridRows = Array.from({ length: rowsCount }, (_, idx) => `auto`).toString();
        }
    
    <GridLayout
        padding="10%"
        columns="auto, auto, auto, auto, auto, auto, auto"
        [rows]="gridRows"
    >
          <ng-container *ngFor="let item of items">
            <label [text]="item.codice" col="0" [row]="item.row" fontSize="24px"></label>
            <label [text]="item.prodotto" col="1" [row]="item.row" fontSize="24px"></label>
            <label [text]="item.lottoData" col="2" [row]="item.row" fontSize="24px"></label>
            <label [text]="item.codiceCont" col="3" [row]="item.row" fontSize="24px"></label>
            <label [text]="item.qtyUntPri" col="4" [row]="item.row" fontSize="24px"></label>
            <label [text]="item.studioCieco" col="5" [row]="item.row" fontSize="24px"></label>
            <label [text]="item.qty" col="6" [row]="item.row" fontSize="24px"></label>
          </ng-container>
        </GridLayout> 
    

    Note: Either use string extrapolation {{ expression }} or binding using square brackets [], but not both, and of course, no need for the comma after col="x" inside the <label> property.