Maverick 2000
Maverick 2000

Reputation: 15

Flutter: 'Future<dynamic>' is not a subtype of type 'String'

I'm trying to build a URL shortner using the following api: https://shrtco.de/docs/. I parsed the JSON file and tried to rebuild the listview. But after adding the url I'm getting the above error. The api seems to be working fine when I print it though. I don't know whats wrong. I'm a beginner in Flutter and Dart. Please help me.

    class _homePageState extends State<homePage> {
  getdata(String userUrl) async {
    //JSON Parser
    var url = 'https://api.shrtco.de/v2/shorten?url=$userUrl';
    var respons = await http.get(url);
    var result = jsonDecode(respons.body);
    var shortlink = result['result']['short_link']; //dictionary parse
    print(shortlink);
    return shortlink;
  }

  Future<String> createAlertDialog(BuildContext context) {
    //method for alertdialog
    //promise to return string
    TextEditingController customController =
        TextEditingController(); //new texteditingc object
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text("Enter URL: "),
            content: TextField(
              controller: customController,
            ),
            actions: [
              MaterialButton(
                elevation: 5.0,
                child: Text("OK"),
                onPressed: () {
                  if (customController.text != null &&
                      customController.text != "") {
                    var getShortlink = getdata(customController.text);
                    item.add(getShortlink);
                  }

                  setState(() {});
                  Navigator.of(context).pop();
                },
              )
            ],
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    String temp;
    return Scaffold(
      appBar: AppBar(
        title: Text("Shortie"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListView.builder(
          itemCount: item.length,
          itemBuilder: (context, index) {
            return ListTile(
              leading: Icon(Icons.link),
              title: Text(item[index]),
              subtitle: Text("data"),
            );
            //return new Text();
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          createAlertDialog(context).then((onValue) {
            temp = onValue;
            print(temp);
          });
        },

Upvotes: 0

Views: 7425

Answers (2)

chunhunghan
chunhunghan

Reputation: 54397

You can copy paste run full code below
Step 1: getdata return Future<String>
Step 2: onPressed need async await
Step 3: put getShortlink in Navigator.of(context).pop(getShortlink);
code snippet

Future<String> getdata(String userUrl) async {
...
onPressed: () async {
      String getShortlink;
      if (customController.text != null &&
          customController.text != "") {
        getShortlink = await getdata(customController.text);
        item.add(getShortlink);
      }

      setState(() {});
      Navigator.of(context).pop(getShortlink);
    },

working demo

enter image description here

full code

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> item = [];

  Future<String> getdata(String userUrl) async {
    //JSON Parser
    var url = 'https://api.shrtco.de/v2/shorten?url=$userUrl';
    var respons = await http.get(url);
    var result = jsonDecode(respons.body);
    var shortlink = result['result']['short_link']; //dictionary parse
    print(shortlink);
    return shortlink;
  }

  Future<String> createAlertDialog(BuildContext context) {
    //method for alertdialog
    //promise to return string
    TextEditingController customController =
        TextEditingController(text: "example.org/very/long/link.html"); //new texteditingc object
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text("Enter URL: "),
            content: TextField(
              controller: customController,
            ),
            actions: [
              MaterialButton(
                elevation: 5.0,
                child: Text("OK"),
                onPressed: () async {
                  String getShortlink;
                  if (customController.text != null &&
                      customController.text != "") {
                    getShortlink = await getdata(customController.text);
                    item.add(getShortlink);
                  }

                  setState(() {});
                  Navigator.of(context).pop(getShortlink);
                },
              )
            ],
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    String temp;
    return Scaffold(
        appBar: AppBar(
          title: Text("Shortie"),
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView.builder(
            itemCount: item.length,
            itemBuilder: (context, index) {
              return ListTile(
                leading: Icon(Icons.link),
                title: Text(item[index]),
                subtitle: Text("data"),
              );
              //return new Text();
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(onPressed: () {
          createAlertDialog(context).then((onValue) {
            temp = onValue;
            print(temp);
          });
        }));
  }
}

Upvotes: 2

krumpli
krumpli

Reputation: 742

createAlertDialog(BuildContext context) doesn't return a Future<String>, it's returns Future<T>, dynamic in your case. https://api.flutter.dev/flutter/material/showDialog.html

Upvotes: 0

Related Questions