Raman Plaha
Raman Plaha

Reputation: 133

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

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,

Upvotes: 10

Views: 33776

Answers (3)

Hemant Singh
Hemant Singh

Reputation: 1

Instead of using CachedNetworkImageProvider directly, I recommend using CachedNetworkImage widget for better handling of network images. Here's why and how you should make the switch:

Incorrect Approach:

Container(
  constraints: BoxConstraints(maxHeight: 80, maxWidth: 80),
  width: size,
  height: size,
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(SizeM),
    image: DecorationImage(
      image: CachedNetworkImageProvider(imageUrl ?? ''),
      fit: BoxFit.cover,
    ),
  ),
);

Correct Approach:

CachedNetworkImage(
  imageUrl: imageUrl ?? '', // Provide the URL directly here
  imageBuilder: (context, imageProvider) => Container(
    constraints: BoxConstraints(maxHeight: 80, maxWidth: 80),
    width: size,
    height: size,
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(SizeM),
      image: DecorationImage(
        image: imageProvider,
        fit: BoxFit.cover,
      ),
    ),
  ),
  placeholder: (context, url) => CupertinoActivityIndicator(), // Placeholder widget while loading
  errorWidget: (context, url, error) => Icon(Icons.error), // Widget to display in case of error
);

Using CachedNetworkImage widget offers more control and flexibility, along with built-in features like placeholder and error handling. It ensures efficient caching and smoother loading of images from network sources.

Upvotes: 0

Sohaib Aslam
Sohaib Aslam

Reputation: 1325

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),
                )

Upvotes: 4

Yago Est&#233;vez
Yago Est&#233;vez

Reputation: 101

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.

Upvotes: 10

Related Questions