3

How I can check if a specific asset exists in Flutter. I'm trying to load some images and sound files and I need to handle the case when these assets do not exist.

I need to check the existence because I have audio files and images for numbers from 1 to 1000. When I build my widgets I use a loop from 1 to 1000 to build it. and there are possibilities that the required file ( the image or the sound for the current number ) does not exist in the assets.

Trevor Reid
  • 3,310
  • 4
  • 27
  • 46
Flutter IO Dev
  • 1,759
  • 5
  • 15
  • 20

4 Answers4

5

you can try my solution, if you use a simple Image.asset Widget:

Image.asset(
'assets/image.jpg',
 errorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
                return Image.network('path');})
AlexF1
  • 365
  • 3
  • 13
  • 1
    Still throws an "Unable to load asset: ... Exception caught by image resource service. The following assertion was thrown resolving an image codec:" – Kernel James Nov 30 '21 at 08:07
4

Following Raouf suggestion I handled the case where the assets not exist.

Image loader widget:

Future<Image> _buildImage() async {
  String path = "assets/images/contents/${content.id}.jpg";
  return rootBundle.load(path).then((value) {
    return Image.memory(value.buffer.asUint8List());
  }).catchError((_) {
    return Image.asset(
      "assets/images/null.png",
      height: 250.0,
    );
  });
}

Using the Image widget inside my build method:

FutureBuilder(
          future: _buildImage(),
          builder: (BuildContext context, AsyncSnapshot<Image> snapshot) {
            if (snapshot.connectionState == ConnectionState.done)
              return snapshot.data;
            else
              return Image.asset("assets/images/null.png");
          },
        ),
      ),
Flutter IO Dev
  • 1,759
  • 5
  • 15
  • 20
  • Better not to call `_buildImage()` this way. Calling it from the `FutureBuilder()` may lead to it being called every frame. See documentation for `FutureBuilder` https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html – kikap Jan 03 '20 at 22:06
  • This doesn't work for me. I get an exception on the ```rootBundle.load``` line and the catchError section doesn't seem to get called. I also tried to put it all in try/catch but that didn't work either. This is very frustrating... – shaimo Jul 06 '20 at 17:02
3

I assume that you are using the AssetBundle class to load your data using the load method which takes ByteData, and when you use this method, it will throws an exception if the asset is not found.

Ilyes
  • 14,640
  • 4
  • 29
  • 55
Raouf Rahiche
  • 28,948
  • 10
  • 85
  • 77
1

For someone that Flutter IO Dev answer did not work because the exception still appears, this worked for me:

Future<Widget> getDevIcon(String path) async {
  try {
    await rootBundle.load(path);
    return Image.asset(path);
  } catch (_) {
    return SizedBox.shrink();
  }
}
Rodrigo porras
  • 196
  • 2
  • 8