Flutter Default Image Placeholder - flutter

In my data i have posts, but some having image urls and others have false value, while displaying i want to show the placeholder where value are false
Here is my code :
child: FadeInImage(
placeholder: AssetImage('assets/images/placeholder.png'),
image: NetworkImage(posts[index].featuredImage.large ) == null ?
Image.asset('assets/images/placeholder.png') : NetworkImage(posts[index].featuredImage.large ),
fit: BoxFit.cover,
),

You don't need to wrap the condition posts[index].featuredImage.large in a NetworkImage widget.
Just check if the string coming from the API is null, then set the default Image as Image.asset('assets/images/placeholder.png') and if it is not null set the Image as NetworkImage(posts[index].featuredImage.large ).
Try the code below:
FadeInImage(
placeholder: AssetImage('assets/images/placeholder.png'),
image: posts[index].featuredImage.large == null ?
Image.asset('assets/images/placeholder.png') : NetworkImage(posts[index].featuredImage.large ),
fit: BoxFit.cover,
),

This how you can do it
child: post[index].url==false? Image.assets('assets/images/placeholder.png'): FadeInImage(
fit: BoxFit.cover,
placeholder: AssetImage('assets/images/placeholder.png'),
image: posts[index].featuredImage.large == null ?
Image.asset('assets/images/placeholder.png') : NetworkImage(posts[index].featuredImage.large ),
),
But there will be an issue here if your url is declared as String since false is not a String and comparing different data type is not a good idea . Then you will have to check RuntimeType
E.g: post[index].url is String//true if url is a String

Related

The method '[]' was called on null. Receiver: null in Flutter

Where do I wrong?
I created this method,
I get no issue in debugger, but when I run the app I get this error.
The following NoSuchMethodError was thrown building:
The method '[]' was called on null.
Receiver: null
Tried calling:
How can I solve this issue?
late String urlImage;
late String urlImageSource;
var _post;
final List<Article> _posts = [
Article(
urlImage: 'urlImage',
urlImageSource: 'urlImageSource',
title: 'title',
description: 'description',
),
];
String checkIfUrlContainPrefixHttps(String urlImageSource) {
if (!urlImageSource.startsWith("//") || !urlImageSource.startsWith("http")) {
return urlImageSource;
} else {
return 'https://' + urlImageSource;
}
}
Widget image
SizedBox(
height: 190,
width: double.infinity,
child: CachedNetworkImage(
imageUrl: checkIfUrlContainPrefixHttps(_post[0].urlImageSource),
fit: BoxFit.cover,
placeholder: (context, url) => Image.asset("assets/gif/shimmer.gif",
width: double.infinity,
height: 190,
fit: BoxFit.cover,
),
errorWidget: (context, url, error) =>
Image.asset("assets/images/unloadedImage.png",
width: 250,
height: 250,
),
),
)
Your _post is null and you are trying to get 0 item in it, try this:
checkIfUrlContainPrefixHttps(_post != null ? _post[0].urlImageSource :'')

Image cannot be null using FadeInImage and url [Flutter]

Hello so I added a way to display my url images in a list but because Im fetching this information from public API some of them are missing URLs and errors occur, I tried using placeholder and image errorbuilder but that didnt help
Here is my code:
child: FadeInImage.assetNetwork(
height: 100,
width: 100,
fit: BoxFit.fill,
image: newsList[index].urlToImage,
placeholder: 'images/placeholder.png',
imageErrorBuilder: (context, error, StackTrace) {
return const Image(
height: 100,
width: 100,
image: AssetImage("images/placeholder.png"));
},
),
and Error:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building:
'package:flutter/src/widgets/fade_in_image.dart': Failed assertion: line 234 pos 15: 'image !=
null': is not true.
Updated Code:
child: newsList[index].urlToImage == null
? Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/placeholder.png"),
),
),
)
: FadeInImage.assetNetwork(
height: 100,
width: 100,
fit: BoxFit.fill,
image: newsList[index].urlToImage,
placeholder: 'images/placeholder.png',
imageErrorBuilder:
(context, error, StackTrace) {
return const Image(
height: 100,
width: 100,
image:
AssetImage("images/placeholder.png"));
},
),
and error message:
imageErrorBuilder will only be called if there is an error occurs during image loading, example the image path does not exist.
To fix your issue, you have to check whether url is null or empty. If it is null, display another widget, else display FadeInImage.
newsList[index].urlToImage == null ? DisplayNoImage: FadeInImage.assetNetwork(...),

Exception has occurred. _TypeError (type 'Container' is not a subtype of type 'String')

I'm trying to show the user image URL In the CircleAvatar(); It's showing a null error even though I've provided it. Or am I doing it wrong?
First I call the Auth Methods and Set image String img,
AuthMethods _auth = AuthMethods();
String img;
I then instantiate in initstate
_auth.getCurrentUser().then((user) async {
setState(() {
user.uid;
img = user.photoUrl
});
});
}
Then call it in the Drawer()
DrawerHeader(
child: CircleAvatar(
backgroundColor: Colors.deepOrange,
radius: 100,
child: Image(
fit: BoxFit.cover,
image: NetworkImage(
img != null ? img : Container(), // <== here
) ??
CircularProgressIndicator(),
),
),
decoration: BoxDecoration(
color: Colors.orange,
),
),
NetworkImage takes a String as perimeter, not a widget.
In your case:
NetworkImage(
img != null ? img : Container(), // <== here
)
if img i.e. String is null than you are returning Container(), but you should return a String (maybe you can give an empty string)
NetworkImage takes image URL in its String parameter, in your case you are passing either image URL or Widget into this parameter and obviously Widget is not String. Your null check should be above NetworkImage like this:
...
image:
img != null ? NetworkImage(img)
:
CircularProgressIndicator(),
//Or container or different desired widget in case image path is null
...

onError method of DecorationImage() in Flutter

Code works fine but because of my unreliable internet connection I am faced with an issue of NetworkImage.load ( See error image below )
Container(
width: 60,
height: 80,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.all(Radius.circular(7.0))
image: DecorationImage(
image: NetworkImage(trend['imageUrl']),
onError: <how we can handle this?>,
fit: BoxFit.cover
),
),
);
I hope this issue can be fixed by handling it on onError method (Correct me if I'm wrong). But I can't figure it out how to do that.
Error:
First of all lets say you intialize NetworkImage inside your class. like:
var imgVariable = NetworkImage(trend['imageUrl']);
Then, load your network image. If, error occurs then we will load from our assets to let user know that we could not load network image.
Container(
width: 60,
height: 80,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.all(Radius.circular(7.0))
image: DecorationImage(
image: imgVariable,
onError: (errDetails){
setState(){
imgVariable = AssetImage('assets/could_not_load_img.jpg');
};
},
fit: BoxFit.cover
),
),
);
Here, assets/could_not_load_img.jpg is image that is imformative sthg.
*Note: This may not seem to work with errors, but this can be a way I came up with. There are plugins like cached_network_image to work beautifully on network images.
The accepted solution by Biplove doesn't seem to work anymore, at least I couldn't solve the resulting cast error when replacing the NetworkImage with an AssetImage. But a similar way would be:
class _YourClassState extends State<YourClass> {
bool networkError = false;
NetworkImage backgroundImage = const NetworkImage(
'youUrl');
AssetImage backgroundImageFallback = AssetImage('assets/img/....jpg');
...
decoration: !networkError ? DecorationImage(
fit: BoxFit.fill,
onError: (Object e, StackTrace? stackTrace) {
log("Could not load the network image, showing fallback instead. Error: ${e.toString()}");
if (stackTrace != null) {
log(stackTrace.toString());
}
setState(() {
networkError = true;
});
},
image: backgroundImage) :
DecorationImage(
fit: BoxFit.fill,
image: backgroundImageFallback)
}
so, onError in flutter basically takes a return type of function
it takes some error that may generate during the loading/fetching of the response image URL as the parameter Error that is generated during call and a report that provides information about program subroutines that can be found in the debug console as well
onError:(error, stackTrace) => AssetImage('assets/could_not_load_img.jpg'),
or you can check these
[click]https://github.com/flutter/flutter/issues/78925#issuecomment-806553363
[click]https://github.com/flutter/flutter/issues/78925

type 'FutureBuilder<File>' is not a subtype of type 'ImageProvider<dynamic>' - Image Picker problem

I need to add an image in a Container. The image is coming from IMAGE PICKER.
Im getting the error:
type 'FutureBuilder<File>' is not a subtype of type 'ImageProvider<dynamic>'
Here's the original code:
Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image:
_imageFileForHeader.path != null?
FutureBuilder(
future: _getLocalFile(_imageFileForHeader.path),
builder: (BuildContext context, AsyncSnapshot<io.File> snapshot)
{
return Image.file(snapshot.data);
}
):
NetworkImage(urlImage + _kHeaderImage), fit: BoxFit.cover,
),
),
I really could do with any help here.
If the user does not select an image from the gallery - then use the image in the URL (urlImage).
I think I'm doing a very standard routine, and I cannot see why its not working.
Thanks
-- I just want to add that I tried also :
return FileImage(snapshot.data)
and this did not work either.
I think I exhausted every permutation possible here.
By the way, here's the _getLocalFile...
Future<io.File> _getLocalFile(String filename) async
{
io.File f = new io.File(filename);
return f;
}
You don't need any future in _getLocalFile as there is no async operations inside. You can just do
return Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image: _imageFileForHeader?.path != null
? Image.file(File(_imageFileForHeader.path))
: Image.network(urlImage + _kHeaderImage);
),
),
Or Assuming _imageFileForHeader is already a file we could simplify this even more
return Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image: _imageFileForHeader != null
? Image.file(_imageFileForHeader)
: Image.network(urlImage + _kHeaderImage);
),
),
I think your _getLocalFile function returns the wrong datatype. Maybe if you try the following:
Future<File> _getLocalFile() async{
final ImagePicker _picker = ImagePicker();
PickedFile pickedFile= await _picker.getImage(source: ImageSource.gallery);
File file = File(pickedFile.path);
return file;
}
Futhermore, I don´t belive that you can use a FutureBuilder for the Containers image variable. To display a image inside a Container you can use:
File file;
Container(
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.cover,
image: new FileImage(file),
),
),
),
So I think you have to check the file variable for null and if it is null, maybe show a button. If the user presses the button, you can call the async _getLocalFile function and than maybe update with setState to show the image.
Maybe you could also wrap the image around a FutureBuilder:
FutureBuilder<File>(
future: _getLocalFile(),
builder: (BuildContext context, AsyncSnapshot<File> snapshot)
{
if(!snapshot.hasData){
return CircularProgressIndicator();
}else{
return Container(
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.cover,
image: new FileImage(snapshot.data),
),
),
);
}
}
);