3

This happened after migrating from Flutter 3.10.5 to 3.24.5.

I have a method on a class that uses a String with the information of what FontWeight to use. Basically, something like this:

final fontWightText = `w400`;
final fontWeight = FontWeight.values.firstWhere(
        (element) => element
            .toString()
            .endsWith(fontWeightText),
      ),

The problem is that, while running the app on release mode, this throws a Bad state: No element error. If I run on debug, it works fine. I noticed that if I print FontWeight.values.first on debug, I get FontWeight.w100, while on release I get Instance of 'FontWeight'.

I'm trying to find a workaround for this, but I also wonder if it might happen elsewhere on my app since it only happens if I run this new version of Flutter.

1
  • While some classes can (and occasionally do) generate more detailed debug strings, AFAICT from the implementation of FontWeight.toString shown in the Flutter 3.27.2 documentation, it does not seem to be one of them. Commented Jan 21 at 17:33

2 Answers 2

3

Interesting question!

toString() will have a different output between debug vs release mode, like you said

It is by design to optimize and reduce a lot of extra information in output log

Basically logic code should not rely on this method since it is mostly just for logging

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for clarifying this! I ended up using the .value property of the instance, which gives me the int value of the element (400 for FontWeight.w400, for example). Considering this information, this seems to be a better way of achieving what I need.
Yeah, I was about to suggest something like that (not because I understood why it did behave differently, I have to admit)
2

As was pointed out in the comments, the toString implementation of FontWeight returns only constants values, so probably the issue is somewhere in your configuration. Maybe you need to update flutter, clear caches or something like that: I'd start by adding some print lines, so you can try do debug what's happening in release mode.

I scribbled up a MRE that you can run in a DartPad, so you can see that with the latest version of flutter it's running as supposed:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final fontWeightText = 'w400';
    final fontWeight = FontWeight.values.firstWhere(
      (element) {
        print(element.hashCode() +' vs '+fontWeightText);
        return element.toString().endsWith(fontWeightText);
      },
    );
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Column(
            children: [
              Text('Hello, World!'),
              Text(
                'Hello, World!',
                style: TextStyle(fontWeight: fontWeight),
              )
            ],
          ),
        ),
      ),
    );
  }
}

2 Comments

It's an interesting way of testing it, but it looks like DartPad only runs on debug mode. Is it possible to run it on release mode to test the difference?
Good point: yesterday I tried too to run DartPad in release mode, but with no success. Today though I discovered that Google added the possibilty to transfer the code from DartPad to IDX, where it's possible to run the code in release mode, and where the issue seems to be exact the same as yours. I've copied the code into Android Studio, and I'll do some tests there, because the issue happened there as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.