最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

flutter - Why am I getting "The operator '[]' isn't defined for the type 'Future&lt

programmeradmin1浏览0评论

I am trying to fetch a single row of data from Supabase using the following code:

// supabase_service.dart
Future<Map<String, dynamic>> fetchTransaction(int id) async {
    return await _supabaseClient
        .from('transactions')
        .select()
        .eq('id', id)
        .single();
  }

I am calling this code from a stateless widget like so:

final int id;
final dbservice = SupabaseService();

  @override
  Widget build(BuildContext context) {
    final transaction = dbservice.fetchTransaction(id);
    // do stuff with result
      Text('TXN ID: ${transaction["id"]}'); // <---error

However, when I try to use 'transaction', I get the following error:

The operator '[]' isn't defined for the type 'Future<Map<String, dynamic>>'

I can't figure out if the error is because I'm trying to access the data incorrectly, or if it's because I need to further process the data in some way before accessing.

I am trying to fetch a single row of data from Supabase using the following code:

// supabase_service.dart
Future<Map<String, dynamic>> fetchTransaction(int id) async {
    return await _supabaseClient
        .from('transactions')
        .select()
        .eq('id', id)
        .single();
  }

I am calling this code from a stateless widget like so:

final int id;
final dbservice = SupabaseService();

  @override
  Widget build(BuildContext context) {
    final transaction = dbservice.fetchTransaction(id);
    // do stuff with result
      Text('TXN ID: ${transaction["id"]}'); // <---error

However, when I try to use 'transaction', I get the following error:

The operator '[]' isn't defined for the type 'Future<Map<String, dynamic>>'

I can't figure out if the error is because I'm trying to access the data incorrectly, or if it's because I need to further process the data in some way before accessing.

Share Improve this question asked Feb 10 at 22:26 AndyAndy 6622 gold badges9 silver badges23 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 2

As @thenry answered, the value is loaded from the database so it won't be immediately available. That's why your variable is a Future, and why you can't access it as you'd do with a normal "now" variable.

You indeed can't use await in the build method, as all UI building has to happen synchronously. I hope that makes sense when you think about it: you always have to render a UI even while the data is loading. At that point you'll typically want to render some UI element that shows that the data is loading.

The simplest way to display a Future value in the UI is to wrap it in a FutureBuilder:

Widget build(BuildContext context) {
  final transaction = dbservice.fetchTransaction(id);
    
  return FutureBuilder<List<String>?>(
      future: transaction,
      builder: (context, snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return Center(
              child: CircularProgressIndicator(),
            );
          case ConnectionState.done:
            if (snapshot.hasError) {
              return Text('ERROR: ${snapshot.error.toString()}');
            } else {
              return Text('TXN ID: ${snapshot.data["id"]}');
            }
          default:
            return Text('Unhandle State');
        }
      },
    ),
}

So you can see that here we handle the three main states:

  • If the data is still loading, we show a CircularProgressIndicator.
  • If there was an error, we show the error in a text box.
  • If the data was loaded, we show the value you tried to show already.

If this is new to you, I also recommend reading:

  • How do I call async property in Widget build method
  • When to use FutureBuilder in Flutter
  • the documentation of FutureBuilder.

You have defined fetchTransaction(int id) as a Future function so when calling it you'll have to add an await statement to reference its return result.

For example,

@override
  Widget build(BuildContext context) {
    final transaction = await dbservice.fetchTransaction(id);
    // do stuff with result
      Text('TXN ID: ${transaction["id"]}'); // <---error

This should allow you to access the key "id" in the returned map, if it exists.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论