try/catch not working on network image (Exception: Invalid image data)

Viewed 15271

I have get network image and used ternary operator where I can show network image but unable to show default asset image where network image is invalid default image in grid also as this-

I am new to flutter

 image: NetworkImage(products[index]
                                              .productImageList[0]
                                  )!= null
                                      ? NetworkImage(
                                      products[index].productImageList[0])
                                      :Image.asset("assets/defimg.jpg"),
                                  fit: BoxFit.fitHeight ),

it shows network image on index 0 but does not load asset image where network image is invalid or null and throw this error-

════════ Exception caught by image resource service ════════════════════════════════════════════════
The following _Exception was thrown resolving an image codec:
Exception: Invalid image data

When the exception was thrown, this was the stack: 
#0      _futurize (dart:ui/painting.dart:5230:5)
#1      ImageDescriptor.encoded (dart:ui/painting.dart:5098:12)
#2      instantiateImageCodec (dart:ui/painting.dart:1998:60)
<asynchronous suspension>

after this i tried try/catch -my code with try catch is --

child: Builder(builder: (BuildContext context) {
                              try {
                                return Center(
                                  child: Image.network(
                                      products[index]
                                                .productImageList[0],
                                      fit: BoxFit.contain,
                                  ),
                                );
                              } catch (e) {
                                print("Got exception ${e.toString()}");
                                return Image.asset("assets/defimg.jpg", fit: BoxFit.contain);
                              }
                            }),

give me same error as above..

image response come from api in a list "productImageList" as shown bellow --

            "sellingPrice": "4000",
            "productImageList": [
                "https://www.xyzz.com/postadsimages/img/23682201.jpg"
            ],
            "createdDate": 1607754473000,

2 Answers

Image.network lets you handle both the loading and error states of the network request, but not the way you tried.

I'll give you an example of what should do instead:

// Just to DRY
final Image noImage = Image.asset("assets/defimg.jpg");
final imageUrl = products[index].productImageList[0];

// Now, in the widget's image property of your first example:
image: (imageUrl != null) // Only use the network image if the url is not null
  ? Image.network(
      imageUrl,
      loadingBuilder: (context, child, loadingProgress) =>
          (loadingProgress == null) ? child : CircularProgressIndicator(),
      errorBuilder: (context, error, stackTrace) => noImage,
    )
  : noImage;

This way you can handle the Invalid image data exception and also show another image while the network one is still being fetched.

PS: You can also use FadeInImage.assetNetwork if you want a fading effect after loading the asset.

CachedNetworkImage

you can use the cachedNetworkImage instead of the image network.

 CachedNetworkImage(
                  imageUrl:
                      "https://store4.gofile.io/download/361b6d89-e4a7-4444-a725-a32bdbfefba6/WhatsApp%20Image%202021-11-03%20at%209.38.00%20PM.jpeg",
                  height: 25.h,
                  width: 100.w,
                  fit: BoxFit.fill,
                )

OR

 CachedNetworkImage(
                  imageUrl: imageURL,
                  fit: BoxFit.fill,
                  placeholder: (context, url) => Padding(
                    padding: EdgeInsets.all(18.0),
                    child: CircularProgressIndicator(
                        strokeWidth: 2, color: MyColors.primary),
                  ),
                  errorWidget: (context, url, error) =>
                      Icon(Icons.person, color: MyColors.grey),
                )
Related