30

I consume API to fetch Image from database . I have response like this :

{
    "status": "ok",
    "message": "Logo Client Is Found",
    "data": [
        {
            "fileInfo": "img-1.png"
        }
    ]
}

I want get that value from API with this code :

 Future<String> getLogoClient() async {
    final response = await _client.get("$_baseUrl/getLogoClient");
    final Map<String, dynamic> responseJson = json.decode(response.body);
    if (responseJson["status"] == "ok") {
      List image = responseJson["data"];
      final imageList =
          image.map((json) => AppInfoModel.logoFromJson(json)).toList();
      final singleImage = imageList.single.fileInfo;
      final String urlImage = "$baseImageUrl/$singleImage";
      print(urlImage);
      return urlImage;
    } else {
      throw CustomError(responseJson["message"]);
    }
  }

Print response :

http://---/images/info/img-1.png

The problem is , i want convert value from Future to String How can i do this ?

I already trying with this code and success convert that value:

String urlImageApi = "";
  _getImage() async {
    final result = await appInfoApi.getLogoClient();
    setState(() {
      urlImageApi = result;
    });
  }

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

But I get error :

I/flutter ( 8408): #644    ComponentElement.performRebuild 
package:flutter/…/widgets/framework.dart:4243
I/flutter ( 8408): #645    Element.rebuild 
package:flutter/…/widgets/framework.dart:3947
I/flutter ( 8408): #646    ComponentElement._firstBuild 
package:flutter/…/widgets/framework.dart:4206
I/flutter ( 8408): #647    StatefulElement._firstBuild 
package:flutter/…/widgets/framework.dart:4381
I/flutter ( 8408): #648    ComponentElement.mount 
package:flutter/…/widgets/framework.dart:4201
I/flutter ( 8408): #649    Element.inflateWidget 
package:flutter/…/widgets/framework.dart:3194
I/flutter ( 8408): #650    Element.updateChild 
package:flutter/…/widgets/framework.dart:2988
I/flutter ( 8408): #651    ComponentElement.performRebuild 
package:flutter/…/widgets/framework.dart:4243
I/flutter ( 8408): #652    Element.rebuild 
package:flutter/…/widgets/framework.dart:3947
I/flutter ( 8408): #653    ComponentElement._firstBuild 
package:flutter/…/widgets/framework.dart:4206
I/flutter ( 8408): #654    ComponentElement.mount 
package:flutter/…/widgets/framework.dart:4201
I/flutter ( 8408): #655    Element.inflateWidget 
package:flutter/…/widgets/framework.dart:3194
I/flutter ( 8408): #656    Element.updateChild 
package:flutter/…/widgets/framework.dart:2988
I/flutter ( 8408): #657    ComponentElement.performRebuild 
package:flutter/…/widgets/framework.dart:4243
I/flutter ( 8408): #658    Element.rebuild 
package:flutter/…/widgets/framework.dart:3947
I/flutter ( 8408): #659    ComponentElement._firstBuild 
package:flutter/…/widgets/framework.dart:4206
I/flutter ( 8408): #660    StatefulElement._firstBuild 
package:flutter/…/widgets/framework.dart:4381
I/flutter ( 8408): #661    ComponentElement.mount 
package:flutter/…/widgets/framework.dart:4201
I/flutter ( 8408): #662    Element.inflateWidget 
package:flutter/…/widgets/framework.dart:3194
I/flutter ( 8408): #663    Element.updateChild 
package:flutter/…/widgets/framework.dart:2988
I/flutter ( 8408): #664    ComponentElement.performRebuild 
package:flutter/…/widgets/framework.dart:4243
I/flutter ( 8408): #665    Element.rebuild 
package:flutter/…/widgets/framework.dart:3947
I/flutter ( 8408): #666    ComponentElement._firstBuild 
package:flutter/…/widgets/framework.dart:4206
I/flutter ( 8408): #667    ComponentElement.mount 
package:flutter/…/widgets/framework.dart:4201
I/flutter ( 8408): #668    Element.inflateWidget 
package:flutter/…/widgets/framework.dart:3194
I/flutter ( 8408): #669    Element.updateChild 
package:flutter/…/widgets/framework.dart:2988
I/flutter ( 8408): #670    RenderObjectToWidgetElement._rebuild 
package:flutter/…/widgets/binding.dart:1028
I/flutter ( 8408): #671    RenderObjectToWidgetElement.mount 
package:flutter/…/widgets/binding.dart:999
I/flutter ( 8408): #672    RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> 
package:flutter/…/widgets/binding.dart:942
I/flutter ( 8408): #673    BuildOwner.buildScope 
package:flutter/…/widgets/framework.dart:2412
I/flutter ( 8408): #674    RenderObjectToWidgetAdapter.attachToRenderTree 
package:flutter/…/widgets/binding.dart:941
I/flutter ( 8408): #675    WidgetsBinding.attachRootWidget 
package:flutter/…/widgets/binding.dart:819
I/flutter ( 8408): #676    WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> 
package:flutter/…/widgets/binding.dart:804
I/flutter ( 8408): #685    _Timer._runTimers  (dart:isolate-patch/timer_impl.dart:384:19)
I/flutter ( 8408): #686    _Timer._handleMessage  (dart:isolate-patch/timer_impl.dart:418:5)
I/flutter ( 8408): #687    _RawReceivePortImpl._handleMessage  (dart:isolate-patch/isolate_patch.dart:174:12)
I/flutter ( 8408): (elided 11 frames from package dart:async and package dart:async-patch)
I/flutter ( 8408):
I/flutter ( 8408): Image provider: NetworkImage("", scale: 1.0)
I/flutter ( 8408): Image key: NetworkImage("", scale: 1.0)
I/flutter ( 8408): ════════════════════════════════════════════════════════════════════════════════════════════════════

I Miss Something ?

5
  • what do you mean by convert Future to String? You can't. Commented Feb 5, 2020 at 5:17
  • You need to use FutureBuilder to access string value from future. Commented Feb 5, 2020 at 5:17
  • it's possible to do without FutureBuilder ? Because properties in my widget only accept String. I success convert from Future<String> to string with above code , app still running and success fetch image , but i get the error like above Commented Feb 5, 2020 at 5:20
  • you can. Why are you using await? If you need ui only after response then you need to use futurebuilder and future otherwise not. Commented Feb 5, 2020 at 5:26
  • you need to check empty string. Commented Feb 5, 2020 at 6:17

4 Answers 4

63

you can use then method and can convert Future to String.

appInfoApi.getLogoClient().then((String result){
setState(() {
      urlImageApi = result;
    });
});
Sign up to request clarification or add additional context in comments.

Comments

5

The reason you are getting an error is because you are await-ing on the initState. Flutter expects that the code in initState to be non-blocking because it can't wait for initState to finish execution, Flutter needs to render the UI elements immediately.

You can do this by using a then method on a Future like here. Another way to do this is using Timer#run method like this:

Timer.run(() async {
    String urlImageApi = await appInfoApi.getLogoClient();
    setState(() {
      urlImageApi = result;
    });
})

The reason the above code works is stated here

Comments

1

in my case, my Future is Future<dynamic>, I solve like this:

appInfoApi.getLogoClient().then((result) {
    setState(() {
       if (result is String)
            urlImageApi = result.toString(); //use toString to convert as String
    });
});

Comments

1

wrap your Image() under a FutureBuilder().

  child: FutureBuilder(
    future: getLogoClient(),
    builder: (context, snapshot) {
      return Image(
        image: NetworkImage('${snapshot.data}'),
      );
    },
  ),

1 Comment

Actually, this answer is a bad practice. Every time the build method is called the FutureBuilder widget will rebuild also and this make the request getLogoClient() triggered multiple times.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.