Search code examples
flutterapidartdart-null-safety

Future<String?> always return null


sorry to bother you, but I have a problem that’s driving me crazy and I could use some help. I’m creating an App and I have to work with APIs, in practice the API (which I’m sure works because the use on my website) must send me an image. To do this I wrote this function :

import 'dart:ui' as ui;
import 'dart:convert';
import 'dart:developer';
import 'package:http/http.dart' as http;

class ApiService{

 static Future<String?> callDalleService({required String promptText}) async {
 var queryStartTime = DateTime.now();

 final uri= Uri.parse('https://surfaces-notebook-biographies-paying.trycloudflare.com/dalle');
 final headers = {'Bypass-Tunnel-Reminder': "go"};
 Map<String, dynamic> body = {'text' : promptText,'num_images' : 1};
 String jsonBody = json.encode(body);
 final encoding = Encoding.getByName('utf-8');
 String? finalImage;

 final response = await http.post(
 uri,
 headers: headers,
 body: jsonBody,
 encoding: encoding,
 ).then((res) {
if(res.statusCode == 200) {
 var jsonResponse = jsonDecode(res.body);
 print(jsonResponse);
 return finalImage = jsonDecode(res.body)['generatedImgs'].toString();
}
 else
 {
 print('An Error occured with the response');
 return null;
 }
 });
 }
}

Then pass the parameter to another page like this :

onTap: () async{
 final promptText = _inputTextController.text;
 print('API call to DALL-E web service with the following prompt $promptText');
 setIsFetchingImgs == true;
 String? finalImage = await ApiService.callDalleService(promptText: _inputTextController.text);
 print(finalImage);
 if (finalImage != null) {
 Navigator.push(context, MaterialPageRoute(builder: (context) =>  new firstOutputPage(finalImage: finalImage),));
 }else{
 print('finalImage returned null');
 }
},

Only for some reason the string is always empty. I tried to spell out the value of the string this way :

return finalImage = "Test value";

But still it always comes back null... Please help me


Solution

  • Don't bother with then in an async function - just use await.

    This snippet works as expected:

    static Future<String?> callDalleService({required String promptText}) async {
      final response = await http.post(
        Uri.parse(
          'https://surfaces-notebook-biographies-paying.trycloudflare.com/dalle',
        ),
        headers: {'bypass-tunnel-reminder': 'go'},
        body: json.encode({'text': promptText, 'num_images': 1}),
      );
    
      if (response.statusCode != 200) {
        return null;
      }
    
      return json.decode(response.body)['generatedImgs'][0];
    }