nativescript-angular icon indicating copy to clipboard operation
nativescript-angular copied to clipboard

iOS - GridLayout with dynamically positioned cells crashes on iOS.

Open sbknick opened this issue 6 years ago • 4 comments

Environment Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 5.3
  • iOS Runtime: 5.1.0
  • NativeScript-Angular: 7.1.0
  • Angular: 7.1.0

Describe the bug On iOS, when a GridLayout child element is positioned using "col" and "row" where the positioning is calculated at runtime---eg [col]="idx % 2" [row]="idx / 2"---this causes a crash on iOS with a TypeError: undefined is not an object (evaluating 'rowGroup.getIsAuto').

To Reproduce

  1. Create a NS Angular project.
  2. Create a component with an arbitrary set of "items":
export class ItemsComponent {
    items = ["Item 1", "Item 2", "Item 3"];
}
  1. In the component's template, attempt to display the items in a GridLayout, calculating the 'col' and 'row' dynamically:
<GridLayout columns="*, *" rows="auto, auto">
    <StackLayout *ngFor="let item of items; let idx = index"
        [col]="idx % 2" [row]="idx / 2">
        <Label [text]="item"></Label>
    </StackLayout>
</GridLayout>
  1. When running the app, on iOS, the app will crash.

Expected behavior The items should be displayed nicely in a grid, evenly spaced horizontally and auto-spaced vertically.

Sample project https://github.com/sbknick/ns-ios-dynamicpositionedgridlayout

Additional context On Android, this functions as expected.

sbknick avatar Apr 25 '19 10:04 sbknick

Hi @sbknick, Thank you for the provided sample project. I was able to recreate the issue on my side for iOS and will mark it as a bug, which we will investigate further. As a temporary solution, I would suggest using braces {{ }}, while setting up the col and row properties binding. For example:

 <GridLayout columns="*, *" rows="auto, auto" style="border-width: 1">
        <StackLayout *ngFor="let item of items; let idx = index"
            col="{{idx % 2}}" row="{{idx / 2}}">
            <Label [text]="item"></Label>
            <Label [text]="idx"></Label>
        </StackLayout>
    </GridLayout>

The code above will work as expected on both iOS and Android.

tsonevn avatar Apr 25 '19 11:04 tsonevn

commenting here due having the same underlying issue on a Nativescript-Vue project.

The suggested workaround with the mustache templating also wasn't working for me with Vue in this instance. So, I came up with a slightly different syntax in case someone else runs across this before this is fixed.

instead of the mustache syntax use the following:

<GridLayout columns="*, *" rows="auto, auto" style="border-width: 1">
  <StackLayout v-for="item of items" :key="index"
      :col="`${ index % 2 }`" :row="`${ index / 2 }`">
    <Label :text="item"></Label>
    <Label :text="index"></Label>
  </StackLayout>
</GridLayout>

jawa-the-hutt avatar Jun 10 '19 14:06 jawa-the-hutt

commenting here due having the same underlying issue on a Nativescript-Vue project.

The suggested workaround with the mustache templating also wasn't working for me with Vue in this instance. So, I came up with a slightly different syntax in case someone else runs across this before this is fixed.

instead of the mustache syntax use the following:

<GridLayout columns="*, *" rows="auto, auto" style="border-width: 1">
  <StackLayout v-for="item of items" :key="index"
      :col="`${ index % 2 }`" :row="`${ index / 2 }`">
    <Label :text="item"></Label>
    <Label :text="index"></Label>
  </StackLayout>
</GridLayout>

Thanks! This worked

dammynex avatar Oct 26 '19 19:10 dammynex

I was having the same issue, but for me it was because I had column="*,*" instead of "columns". Check your syntax, friends!

jarrodwhitley avatar Dec 03 '21 16:12 jarrodwhitley