4

I tried some other solutions to this like using asMap() and forEach but kept getting different errors. Like it was saying the return type of my ChartBar isn't a 'MapEntry', as defined by anonymous closure, or The expression here has a type of 'void', and therefore cannot be used.

Row(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: myList.map((data) {
      return ChartBar(
          ///etc
    }).toList(),
  )

I want the index as well.

Hasen
  • 11,710
  • 23
  • 77
  • 135

2 Answers2

9

mirkancal's suggestion didn't work because Map.map returns another Map (and therefore the enumeration callback you pass it is expected to return a MapEntry).

You instead need to use Map.entries so that you can use Iterable.map instead to construct a List:

Row(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: myList.asMap().entries.map((MapEntry entry) {
      return ChartBar(entry.key, entry.value);
    }),
  )

You alternatively can use Dart's new collection-for construct:

Row(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: [for (MapEntry entry in myList.asMap().entries)
      ChartBar(entry.key, entry.value)
    ],
  )

In the above, entry.key will be the index, and entry.value will be the original value in myList.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
-1

For the index you could use indexOf(value) function from the list to get index value. For example:

List list = List.generate(3, (int index) => index * index); // [0, 1, 4]

list.indexOf(4) // returns 2

As for your other issue, I'd need to see more code to see how you populate myList. I would suggest this approach (if it fits) to render your Row children. Use a function to return that list, for example:

buildList() {
 List<Widget> list = List<Widget>();

 chartBars.forEach((chart) => { //chartBars list with info
  // add your ChartBar widget to the list with appropiate info
  list.add(ChartBar(someProperty: chart.property));
 });
 return list;
}

Then on your Row widget just call that function when you build it's children:

Row(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: buildList()      
)
Rodolfo Franco
  • 431
  • 3
  • 11
  • Splitting widgets to methods is an antipattern though. https://iirokrankka.com/2018/12/11/splitting-widgets-to-methods-performance-antipattern/ – mirkancal Aug 23 '19 at 15:52
  • Is there no simpler way to do it? There's no simple tweak to my existing code just to get the index to display? – Hasen Aug 23 '19 at 15:52
  • @mirkancal thanks for the heads up, I'm relatively new to Flutter and may not be aware of best practices, @Hasen Have you tried using `myList.indexOf(data)` to show the index? – Rodolfo Franco Aug 23 '19 at 15:59
  • 1
    Using `indexOf()` would be rather inefficient, making what should be an O(n) operation instead O(n^2). – jamesdlin Aug 23 '19 at 16:15
  • @mirkancal Yes `indexOf()` works but like it doesn't seem like the most eloquent way to do it. – Hasen Aug 23 '19 at 16:18
  • This will not work if there are duplicate items in the list. – tmath Dec 23 '22 at 12:15