flutterdartstatelesswidget

Trying to build a future context but my build method has an error


I have this code and the problem is that: 'ProfileView.build' ('Future<Widget> Function(BuildContext)') isn't a valid override of 'StatelessWidget.build' ('Widget Function(BuildContext)').

I tried to remove future but it doesn't work, any idea?

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:maze/authentication/bloc/authentication_bloc.dart';
import 'package:maze/core/drawer.dart';
import 'package:webview_flutter/webview_flutter.dart';

import '../../authentication/bloc/authentication_state.dart';
import '../../core/secure_store.dart';

class ProfileView extends StatelessWidget {
  const ProfileView({Key? key}) : super(key: key);

   @override
  Future<Widget> build(BuildContext context) async {
    var state = BlocProvider
        .of<AuthenticationBloc>(context)
        .state;
    var token = await SecureStore().credentials;

    final Completer<WebViewController> _controller =
    Completer<WebViewController>();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Profile'),
        actions: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              child: Text("name",
                  style: new TextStyle(fontWeight: FontWeight.bold)),
              alignment: Alignment.bottomCenter,
            ),
          ),
        ],
      ),
      drawer: const CustomDrawer(),
      body: BlocBuilder<AuthenticationBloc, AuthenticationState>(
        builder: (context, state) {
          return Center(
              child: WebView(
                javascriptMode: JavascriptMode.unrestricted,

                onWebViewCreated: (WebViewController webViewController) {
                  webViewController.loadUrl(
                      "http://exemple.../",
                      headers: {"Authorization": "Bearer ${token}"});
                  _controller.complete(webViewController);
                },
              
              )
          );
        },
      ),
    );
  }

}

Solution

  • I understood that you wanted to have your build method as async because you want to wait for the token to be initialized, but there is a better way to achieve this and here is the solution:

    import 'package:flutter/material.dart';
    
    class ProfileView extends StatefulWidget {
      const ProfileView({Key? key}) : super(key: key);
    
      @override
      _ProfileViewState createState() => _ProfileViewState();
    }
    
    class _ProfileViewState extends State<ProfileView> {
      var state;
      var token;
    
      @override
      void initState() {
        super.initState();
        state = BlocProvider
            .of<AuthenticationBloc>(context)
            .state;
        initToken();
      }
    
      initToken() async {
        token = await SecureStore().credentials;
      }
    
      @override
      Widget build(BuildContext context) {
        final Completer<WebViewController> _controller = Completer<WebViewController>();
    
        return Scaffold(
          appBar: AppBar(
            title: const Text('Profile'),
            actions: [
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Align(
                  child: Text("name",
                      style: new TextStyle(fontWeight: FontWeight.bold)),
                  alignment: Alignment.bottomCenter,
                ),
              ),
            ],
          ),
          drawer: const CustomDrawer(),
          body: BlocBuilder<AuthenticationBloc, AuthenticationState>(
            builder: (context, state) {
              return Center(
                  child: WebView(
                    javascriptMode: JavascriptMode.unrestricted,
    
                    onWebViewCreated: (WebViewController webViewController) {
                      webViewController.loadUrl(
                          "http:exemple...",
                          headers: {"Authorization": "Bearer ${token}"});
                      _controller.complete(webViewController);
                    },
                  )
              );
            },
          ),
        );
      }
    }
    

    Read about the widget lifecycle, it would help you understand why you had the error in the first place.