[Solved] How to identify the List is empty, to avoid the Bad state: No element for ListMixin.reduce

Question

Asked by Elam on January 05, 2022 (source).

I am trying to calculate set of values based on user selection. I am using the reduce method to calculate it.

Its checking for the respective values in the list and throws this error since there is no data in the list.

I am struck in how to resolve this, below i have attached the code.

  get products => _products;

  get productSubtotal => _products.entries
      .map((product) => product.key.price * product.value)
      .toList();


  get total => _products.entries
      .map((product) => product.key.price * product.value)
      .toList()
      .reduce((value, element) => value + element)
      .toStringAsFixed(2);
}

below i have attached the error message.

Bad state: No element

The relevant error-causing widget was: 
  Obx Obx:file:///Users/elamparithibalakrishnan/workspace/purple_star/lib/widgets/cart_total_value.dart:14:12
When the exception was thrown, this was the stack: 
#0      ListMixin.reduce (dart:collection/list.dart:222:22)
#1      CartController.total (package:purple_star/screens/cart/cart_controller.dart:40:8)
#2      CartTotalWidget.totalController (package:purple_star/widgets/cart_total_value.dart:34:19)
#3      CartTotalWidget.build.<anonymous closure> (package:purple_star/widgets/cart_total_value.dart:27:15)
#4      Obx.build (package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart:70:28)
#5      RxInterface.notifyChildren (package:get/get_rx/src/rx_types/rx_core/rx_interface.dart:26:27)
#6      _ObxState.build (package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart:54:19)
#7      StatefulElement.build (package:flutter/src/widgets/framework.dart:4782:27)

Thanks in advance.

Answer

Question answered by Lesiak (source).

I find that you overcomplicated the problem. What you should be asking is how to sum a list of numbers.

The answer is sum extension method from IterableExtension

Note that this method is specialized for List<num>, List<int> and List<double>, it will return correct result type

import 'package:collection/collection.dart';

List<num> nums1 = [1, 2, 3.0];
var s1 = nums1.sum;  // s1 is inferred to num

List<double> nums2 = [1.0, 2.0, 3.0];
var s2 = nums2.sum;  // s2 is inferred to double

List<int> nums3 = [1, 2, 3];
var s3 = nums3.sum;  // s3 is inferred to int

As an additional benefit you can call sum directly on an Iterable, without convering it to list:

var nums = [1, 2, 3.0];
var sumOfSquares = nums.map((x) => x * x).sum;
print(sumOfSquares);

See What is the cleanest way to get the sum of numbers in a collection/list in Dart?

To answer your original question:

You were probably looking for the fold<T> method

T fold<T>(
   T initialValue,
   T combine(T previousValue, E element)
)

Contrary to reduce, fold allows you to specify initial element - empty list is no longer a problem.

DART FLUTTER REDUCE
SHARE: