7

I am trying to access a property in a class in Dart with a dynamic variable. In JavaScript I can use bracket notation and do something like:

var icons = {
  mars: "male",
  venus: "female"
};

getIcon = genderIcon => {
  return icons[genderIcon];
};

console.log(getIcon("mars")); // Prints "male"

Can I do something similar in Dart?

I tried two approaches in Dart but got two different errors which I am not really understanding:

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class GenderSelection extends StatelessWidget {
  final IconData genderIcon;

  GenderSelection({@required this.genderIcon});

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Icon(
        // Using dot notation...
        FontAwesomeIcons.genderIcon // error: The getter 'genderIcon' isn't defined for the class 'FontAwesomeIcons'. (undefined_getter at [bmi_calculator] lib/input_page.dart:71)

        // ...or using bracket notation like JS
        FontAwesomeIcons[genderIcon] // error: The operator '[]' isn't defined for the class 'Type'. (undefined_operator at [bmi_calculator] lib/input_page.dart:71)
      ),
    );
  }
}

Edit

I am adding the complete code to try to explain better what I am trying to achieve. Moreover this is about DYNAMICALLY accessing a property of a class in Dart. It is NOT about icons or FontAwesome.

This is the complete code:

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class InputPage extends StatefulWidget {
  @override
  _InputPageState createState() => _InputPageState();
}

class _InputPageState extends State<InputPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: SafeArea(
          child: Column(
            children: <Widget>[
              Expanded(
                child: Row(
                  children: <Widget>[
                    BmiCard(
                      cardChild: GenderSelection(
                        genderIcon: 'mars', // Comment#1: This won't work. 
                        genderLabel: 'male',
                      ),
                    ),
                    BmiCard(
                      cardChild: GenderSelection(
                        genderIcon: 'venus', // Comment#2: This won't work.
                        genderLabel: 'female',
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class GenderSelection extends StatelessWidget {
  final IconData genderIcon;
  final String genderLabel;

  GenderSelection({@required this.genderIcon, @required this.genderLabel});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        children: <Widget>[
          Icon(
            FontAwesomeIcons().genderIcon, // Comment#3: This doesn't work.
          ),
          Text(
            genderLabel.toUpperCase(),
          ),
        ],
      ),
    );
  }
}

class BmiCard extends StatelessWidget {
  final int color;
  final Widget cardChild;
  BmiCard({this.color = 0xFF1d1e33, this.cardChild});

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        child: cardChild,
      ),
    );
  }
}

It will work If I change the lines in the comments to: - Comment#1: genderIcon: FontAwesomeIcons.mars, - Comment#2: genderIcon: FontAwesomeIcons.venus, - Comment#3: genderIcon,

2
  • 2
    If you're asking if you can look up a property by string in Dart, no, you can't. You would need to implement a lookup table by String yourself. Commented Apr 19, 2020 at 20:35
  • 2
    Thanks @jamesdlin. This was already pretty close to the answer already. I don't get why the question itself was downvoted. I would like to know in order to make better questions in the future and to try to improve this one also. Commented Apr 20, 2020 at 5:48

2 Answers 2

3

The problem here is that the FontAwesomeIcons library does not have a dynamic getter defined. There's nothing you can do to get dynamic object fetching to work on your side.

However, in your particular scenario, you can just initialize a few variables with FontAwesomeIcons that you can then use wherever you want, or use the FontAwesomeIcons' objects by directly referencing them (as you have noted at the end of your post).

There are other ways to achieve the same result, like hard-coding a map of icon names to the icon objects from the FontAwesomeIcons library. But there is no way to dynamically get a object from the class, because the getter has not been defined.

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

1 Comment

I might not have seen the forest from the trees here. Of course if the class doesnt give me the possibility to dynamically fetch the (in this case) icon, there is no way I would be able to access it. Thank you for pointing me in the right direction.
0

I had a similar challenge using font awesome icons that I was able to create a solution that could be helpful or at least thought provoking.

Short Answer

You can access the icons dynamically by passing the Unicode int value of the icon to the FontAwesome IconDataSolid widget

int unicodeIconString = 0xf1b9;
Icon(IconDataSolid(unicodeIconString))

Detailed Answer

My challenge was that I am using a CMS to manage content in a Flutter app. The icons are specified by a json file that loaded at run time. Initially I created a map of strings to FontAwesome icons, but I didn't want to maintain a map of icons in my own flutter code base.

My workable, but not so elegant solution was to place Unicode string in the fields in my database. Ex: '0xf1b9' for the car icon. The FontAwesomeIcons class with this mapping is generated and found here (your path will be slightly different): {your_flutter_sdk_path}/flutter/.pub-cache/hosted/pub.dartlang.org/font_awesome_flutter-8.8.1/lib/font_awesome_flutter.dart

When I pull the Unicode icon string (unicodeIconString) from the database I parse the string to an int and then pass it to IconDataSolid from the Flutter FontAwesome library:

Icon(IconDataSolid(int.parse(unicodeIconString)))

This allows me to dynamically access all the FontAwesome icons without manually creating a map. An obvious down-side is that my database has non-english unicode strings that need to be looked up when I modifying them.

Comments

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.