Cannot return Null from a non-nullable type function - flutter

This is the error message I am getting:
The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type.
Try adding either a return or a throw statement at the end.
on the following code:
Product findProductById(String prodId) {
_productsList.firstWhere((element) {
return prodId == element.id;
});
}
I want to find the Product by its id but if its not found what should I return?

You're not returning inside the findProductById function:
Product findProductById(String prodId) {
return _productsList.firstWhere((element) {
return prodId == element.id;
});
}

From Dart 2.12 and up, we need to specify whether if a type is nullable or non-nullable.
In your case, you should add '?' question mark after the type name Product as you can see below, which will tell the compiler that your function can return a nullable product.
Also you forgot to return the filtered product from the productList.
Product? findProductById(String prodId) {
return _productsList.firstWhere((element) {
return prodId == element.id;
});

You can return a empty Product it's not found.
Product findProductById(String productId) {
return productList.firstWhere((element) => element.id == productId,
orElse: () => Product() // make a empty product using default constructor);
}

Related

Bad state: no element, I want to fetch object from my class file

Errors are thrown by firstwhere method which can be called on Lists
I have a class named Products that holds objects of product(which is model of how each product is) every product object has its own unique id generated using DateTime.now.toString()
Now here I have 2 paths,
**first: ** if I press the update button on my app i will be updating the product already there in my list which i can find using _productList.firstWhere and it will return me my product without any error
option 2
I add a new product with new id, now i have to check where this id product is already there in my list or not
I am using this logic to check whether the id String is available in my list of products or not
bool hasId(String prod_id) {
late bool result;
_items.firstWhere((element) {
if (element.id == prod_id) {
result = true;
}
if (element.id != prod_id) {
result = false;
}
return result;
});
return result;
}
PROBLEM HERE IS
it throws error when it don't find any object with this test
ERROR IS
The following StateError was thrown while handling a gesture:
Bad state: No element
I WANT TO KNOW THAT IT COULDNT FIND ANY OBJECT WITH THAT ID WITHOUT THROWING AN ERROR
NOTE THAT:
_ITEMS HOLD OBJECTS WHICH HAVE ID, ALSO I WANT TO RETURN STRING
I TRIED, orElse: on firstWhere but it wants an object to be returned which I don't have
_item.firstWhere() will return your item Model not boolean.
So, you may do as the following:
List<Product?> _products = [
Product(id: '123', name: 'P1'),
Product(id: '124', name: 'P2'),
];
bool hasId(String productId) {
bool isExist = false;
Product? product = _products.firstWhere((product) => product?.id == productId, orElse: () => null);
if (product != null) {
isExist = true;
}
return isExist;
}

type 'Null' is not a subtype of type 'bool' in type cast

I have Created a Map<String,bool>(in which the key are of type String and the values are of type Boolean) in flutter and When I want to use the bool values in if condition it give me error saying "A nullable expression can't be used as a condition.
Try checking that the value isn't 'null' before using it as a condition."
When I use "as bool" then the error is gone but the program is not executed properly and give me the error in the pic
//this is the code
Map<String, bool> _userFilters = {
"gluten": false,
"lactose": false,
"vegan": false,
"vegetarian": false,
};
List<Meal> filteredMeal = DUMMY_MEALS;
void saveFilters(Map<String, bool> filteredData) {
setState(() {
_userFilters = filteredData;
filteredMeal = DUMMY_MEALS.where(
(meal) {
if (_userFilters['gluten']as bool) { // _userFilter['gluten'] is giving error
return false;
}
if (_userFilters['lactose']as bool) {
return false;
}
if (_userFilters['vegan']as bool) {
return false;
}
if (_userFilters['vegetarian'] as bool) {
return false;
}
return true;
},
).toList();
});
}
No need to cast your map entries to booleans. use an exclamation mark at the end of your variable (e.g, _usedFilters['gluten']!) to treat it as non-nullable.
Rewrite all your conditions like this (if you're sure that the value won't be null):
if (_userFilters['gluten']!) {
return false;
}
if (_userFilters['lactose']!) {
return false;
}
if (_userFilters['vegan']!) {
return false;
}
if (_userFilters['vegetarian']!) {
return false;
}
From Dart.dev:
“Casting away nullability” comes up often enough that we have a new
shorthand syntax. A postfix exclamation mark (!) takes the expression
on the left and casts it to its underlying non-nullable type.

A value of type 'Null' can't be returned from the method 'fetchById' because it has a return type of 'Location'

static Location fetchById(int id) {
List<Location> locations = Location.fetchAll();
for (var i = 0; i < locations.length; i++) {
if (locations[i].id == id) {
return locations[i];
}
}
return null;
}
// if the condition is not true then return null when I try to return null or false it gives the error 'A value of type 'Null' can't be returned from the method 'fetchById' because it has a return type of 'Location'.
With null-safety feature in the dart language, you have to explicitly tell if you want to make a value nullable.
Define the return type with a ?, so dart knows that return value can be null.
static Location? fetchById(int id)
{
/// function body
}

How to check if Dart List contains certain object instance?

I have a Dart List<Book> bookList; Somewhere in the code it has been filled with books.
How can I check if the bookList contains an instance of a Book?
I tried this
if(bookList.contains(Book))
But it didn't work.
You can use is to check the type of the List.
if (bookList is List<Book>) {
print("Yes");
}
You could test the following:
if (bookList.every((item) => item != null && item is Book)) {
...
}
If your bookList is by design a List, testing for nullity is enough:
if (bookList.every((item) => item != null)) {
...
}
If you want to prevent null elements inside the list, you should enforce it also when you add/update element to your list.
First of, you annotated the type of your bookList with List<Book> meaning that any instance should be a Book or null when the list is not empy.
As many others pointed out already, the is is used to test if an object has a specified type. In your case that does not fully solve your problem. If your list contains null, the code
if (bookList is List<Book>) {
print("Yes");
}
will produce Yes. You have to check it like so:
class Book {
String title;
Book(this.title);
}
void main() {
List<Book> bookList = [
Book('foo'),
null,
];
if ((bookList?.length != 0 ?? false) && (!bookList?.contains(null) ?? false) && bookList is List<Book>) {
print("Yes");
} else {
print("No");
}
}
to provide null-safety.
EDIT Updated my answer to be null safe towards bookList being null.
Check the docs:
is test operator: https://dart.dev/guides/language/language-tour#type-test-operators
null-safety: https://dart.dev/null-safety/understanding-null-safety

JPA Specification and null parameter in .where clause

I wrote two Specifications which return null if their parameter is null.
public static Specification<Prodotto> getProdottoByLineaSpec (String linea) {
if (linea != null) {
return (root, query, criteriaBuilder) -> {
return criteriaBuilder.like((root.join("linea")).get("nome"), "%"+linea+"%");
};
}
else return null;
}
public static Specification<Prodotto> getProdottoByIngSpec (String ing) {
if (ing != null) {
return (root, query, criteriaBuilder) -> {
return criteriaBuilder.like(((root.join("listaQuoteIng")).join("ing")).get("nome"), "%"+ing+"%");
};
}
else return null;
}
Then I created a third one that combines the previous ones with an and operator inside a where clause:
public static Specification<Prodotto> getProdottoByMainTraits (String linea, String ing) {
return Specification.where(getProdottoByLineaSpec(linea).and(getProdottoByIngSpec(ing)));
}
Now, that's the funny part:
If ByLinea returns null, i get a nullPointerException from checkPackageAccess when resolving the where clause.
If ByIng returns null, it just gets ignored (like it should be) and the query matches just the other predicate.
If I switch the two predicates, putting ByIng as the first one and then ByLinea inside the where clause, everything works in every combination.
It is a good practice to avoid returning null from methods.
You can use criteriaBuilder.conjunction() to ignore null parameter Specification. It generates always true Predicate. There is an opposite method criteriaBuilder.disjunction()
public static Specification<Prodotto> getProdottoByLineaSpec (String linea) {
return (root, query, criteriaBuilder) -> {
if (linea == null) {
return criteriaBuilder.conjunction();
}
return criteriaBuilder.like(
(root.join("linea")).get("nome"),
"%" + linea + "%"
);
}
}
P.S. You get NullPointerException if first Specification is null trying to access a method and.
To be clear it looks like this
Specification.where(null.and(getProdottoByIngSpec(ing)));
But if only second Specification is null this one works
Specification.where(getProdottoByLineaSpec(linea).and(null));
because and method parameter can be null