4

I'm trying to use ListPicker with an object array and my list gets rendered with the label displaying [object Object] for all elements.

I would like to specify which property to use as the "label" for the listpicker.

Unfortunately Nativescript ListPicker only accepts an array of strings and I can't use my Object array as the label will call toString()

I found an alternative solution based on: https://github.com/NativeScript/NativeScript/issues/1677

buy my app uses page-router-outlet and doesn't use element so I have no way of using the proposed approach above. Given this scenario are there any possible ways of using ListPicker with object arrays or any workaround that doesn't rely on Page element loaded event ?

guilhebl
  • 8,330
  • 10
  • 47
  • 66

2 Answers2

7

There's an undocumented pull request that makes binding to objects much easier: https://github.com/NativeScript/NativeScript/pull/6033

Adds new properties to the ListView component (textField and valueField - should be used with arrays of JSON objects):

textField - tells the listview which property should be used to display each item.

valueField - tells the listview, which property should be used to update the selectedValue.

selectedValue - is the property that will contain the selectedValue, if valueField is specified, then it will contain the value from that property, otherwise it will contain the whole selected item

Example (Angular):

<ListPicker [items]="printers" textField="name" valueField="id"></ListPicker>

In class:

const printers = [{name: "Printer 1", id: 1}, {name: "Printer 2", id: 2}];
Community
  • 1
  • 1
DarkNeuron
  • 7,981
  • 2
  • 43
  • 48
5

You don't have to use any loaded event at all. Simply override the toString method and pass the items to the ListPicker:

  public countries: any[] = [
    {
      value: 0,
      name: 'Sweden',
      toString: () => {
        return 'Sweden';
      }
    },
    {
      value: 1,
      name: 'Denmark',
      toString: () => {
        return 'Denmark';
      }
    },
    {
      value: 2,
      name: 'Norway',
      toString: () => {
        return 'Norway';
      }
    },
    {
      value: 3,
      name: 'Finland',
      toString: () => {
        return 'Finland';
      }
    },
    {
      value: 4,
      name: 'Iceland',
      toString: () => {
        return 'Iceland';
      }
    },
  ];

Pass em to the picker:

<ListPicker [items]="countries"></ListPicker>
Chrillewoodz
  • 27,055
  • 21
  • 92
  • 175
  • Say I have a button that when pushed dynamically changes the toString method on all the countries objects. The ListPicker isn't picking up the changed toString method until I scroll the listpicker. Is there something special you have to do to get the changedetection to work with objects? – apricity May 22 '17 at 16:29
  • 1
    @apricity Update the reference as well with the spread operator `this.myData = [...myData]` or perhaps you need to use `changeDetectorRef.markForCheck()`. Hard to tell without an example. – Chrillewoodz May 24 '17 at 13:53
  • markForCheck() worked: I was getting confused and using detectChanges() before. This helped: https://stackoverflow.com/questions/41364386/whats-the-difference-between-markforcheck-and-detectchanges – apricity May 24 '17 at 20:13