Search code examples
flutterdartscopereturnfuture

Flutter/Dart - Why does my Future return Null?


I want to return a string extracted from the response.body of an Http Post. But my code returns null instead of the string. The string oldname will print just fine if I put it in the scope of request.send() but I need it to be returned when calling the uploadAudio method. What am I doing wrong?

Future<String> uploadAudio({String currentuserid, String filepath}) async {

  String oldname; 
  final serverurl = "http://example.com/audiofile.php";

  var request = http.MultipartRequest('POST', Uri.parse(serverurl));
  request.fields['userid'] = currentuserid;    

  var multiPartFile = await http.MultipartFile.fromPath("audio", filepath,
      contentType: MediaType("audio", "mp4"));
        request.files.add(multiPartFile);
        request.send().then((result) async {
          http.Response.fromStream(result).then((response) {
                if (response.statusCode == 200) {
                  String serverResponse = response.body;
                  const start = "gxz";
                  const end = "zxg";
                  final startIndex = serverResponse.indexOf(start);
                  final endIndex = serverResponse.indexOf(end, startIndex + start.length);
                  oldname = serverResponse.substring(startIndex + start.length, endIndex);
                }
          });
   });
    print oldname;
    return oldname;
  }

Solution

  • I think your confusion comes from the fact you are mixing the use of await and then(). I will recommend you are staying with one concept in general.

    I have rewritten your code so it is now using await everywhere (also cleaned it a little bit up):

    Future<String> uploadAudio({String currentuserid, String filepath}) async {
      const serverurl = "http://example.com/audiofile.php";
    
      final request = http.MultipartRequest('POST', Uri.parse(serverurl))
        ..fields['userid'] = currentuserid;
    
      final multiPartFile = await http.MultipartFile.fromPath("audio", filepath,
          contentType: MediaType("audio", "mp4"));
    
      request.files.add(multiPartFile);
    
      final response = await http.Response.fromStream(await request.send());
      String oldname;
    
      if (response.statusCode == 200) {
        final serverResponse = response.body;
        const start = "gxz";
        const end = "zxg";
        final startIndex = serverResponse.indexOf(start);
        final endIndex = serverResponse.indexOf(end, startIndex + start.length);
        oldname = serverResponse.substring(startIndex + start.length, endIndex);
      }
    
      print(oldname);
      return oldname;
    }
    

    As you can see, the code are much easier to read now without all that nested then() methods.