nativescript-angular
nativescript-angular copied to clipboard
iOS - GridLayout with dynamically positioned cells crashes on iOS.
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
- Create a NS Angular project.
- Create a component with an arbitrary set of "items":
export class ItemsComponent {
items = ["Item 1", "Item 2", "Item 3"];
}
- 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>
- 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.
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.
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>
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
I was having the same issue, but for me it was because I had column="*,*" instead of "columns". Check your syntax, friends!