Flutter: type 'Future<Dynamic>' is not a subtype of type widget

Asked

Viewed 2,743 times

0

I’m trying to run a check through the token:

If there is a token, display the page Home and, if not, displays the page Login.

I tried this way:

main.Dart:

class MyApp extends StatelessWidget {

    // Create storage
    final storage = new FlutterSecureStorage();
    checkHome() async {
    // Read value 
    String token = await storage.read(key: 'token');
    if(token != null){
      return HomePage();
    }else{
      return LoginPage();
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cadê meu pet?',
      theme: ThemeData(primarySwatch: Colors.yellow),
      home: checkHome(),
    );
  }
}

However, I am getting:

type 'Future' is not a subtype of type 'Widget'

I cannot return to home/login through this function?

I also tried to:

void main() async {
  // Set default home.
  Widget _defaultHome = new LoginPage();

  // Read value 
  final storage = new FlutterSecureStorage();
  String token = await storage.read(key: 'token');
  if (token != null) {
    _defaultHome = new HomePage();
  }

  // Run app!
  runApp(new MaterialApp(
    title: 'Cadê meu pet?',
    theme: ThemeData(primarySwatch: Colors.yellow),
    home: _defaultHome,
  ));
}
  • His method checkHome() has the asynchronous assignment. This is because you have inserted the async, with that the return is something in the future (Future as it is getting in error). Already the component that the flutter class is waiting for is of the type Widget and as its return is another type occurs error. One of the solutions to your problem would be the definition of a variable that receives the resolution of the future method and from it choose with a ternary which page you want to display.

  • how can I receive the resolution of my method?

1 answer

2


Its return shows that the component expects to be passed to it an element of the type Widget but you’re passing an element of the kind Future<Widget>. Futures are returned whenever the method has in its signature the declaration async.

In your case an example you can use is:

Example with Statefulwidget

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  // Create storage
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // Variável de controle
  bool temToken = false;

  final storage = new FlutterSecureStorage();

  checkHome() async {
    // Read value
    String token = await storage.read(key: 'token');
    setState(() {
      temToken = token != null;
    });
  }

  @override
  void initState() {
    super.initState();

    checkHome();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cadê meu pet?',
      theme: ThemeData(primarySwatch: Colors.yellow),

      /// Declaração do ternário para escolher qual page exibir
      home: temToken ? HomePage() : LoginPage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Text("Home"),
      ),
    );
  }
}

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Text("Login"),
      ),
    );
  }
}

There are other approaches that could be used, but given the example that passed the question, this is one of the simple ways for this specific scenario that presented.

  • Cool, I added a debugPrint(temToken.toString()); and it returns true, but in ternary condition is returning the login screen, the element to the left of the condition is true, right? should not go to the home screen?

  • I analyzed it better and now it’s taking the value of bool temToken = false;, so it shows the login screen, but even when it changes to true it already rendered the login screen and does not change to home screen.

  • 1

    From what I understand of your scenario this is the first screen of the app. As it depends on a condition I advise using a StateFull. I’ll add the example with Statefull so I can follow it better.

  • This way it worked as expected. Thanks, I could learn a little

  • 1

    To make it simpler then for future community queries, I removed the example that didn’t work as expected and left only the example that met the demand.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.