I am getting an undefined name error even when i defined the var in my dart file, Below is the error image
Below is my code
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/products.dart';
class ProductDetailsScreen extends StatelessWidget {
// final String title;
// ProductDetailsScreen(this.title);
static const routeName = '/product-detail';
@override
Widget build(BuildContext context) {
final productId = ModalRoute.of(context)?.settings.arguments as String?;
if (productId != null) {
final loadedProduct = Provider.of<Products>(context)
.items
.firstWhere((prod) => prod.id == productId);
}
return Scaffold(
appBar: AppBar(
title: Text(loadedProduct.title),
),
);
}
}
plus when i try to move the return code-block to the if method like this
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/products.dart';
class ProductDetailsScreen extends StatelessWidget {
// final String title;
// ProductDetailsScreen(this.title);
static const routeName = '/product-detail';
@override
Widget build(BuildContext context) {
final productId = ModalRoute.of(context)?.settings.arguments as String?;
if (productId != null) {
final loadedProduct = Provider.of<Products>(context)
.items
.firstWhere((prod) => prod.id == productId);
return Scaffold(
appBar: AppBar(
title: Text(loadedProduct.title),
),
);
}
}
}
it then throws an error "the body might complete normally, causing null to be returned, but the return type, "widget" is a potentially non-nullable type.
Please i need help as it looks like my unfamiliarity with null-safety is giving me lot of bugs.
CodePudding user response:
Yes, you have your variable defined, but it is not visible in the place where you want to use it.
In your first snippet:
if (productId != null) {
final loadedProduct = Provider.of<Products>(context)
.items
.firstWhere((prod) => prod.id == productId);
}
return Scaffold(
appBar: AppBar(
title: Text(loadedProduct.title),
),
);
You created loadedProduct
but it is only accessible within {}
brackets of your if statement. It is called Lexical Scoping
.
In yours second snippets you can see that you try to use loadedProduct
variable in a proper scope - it doesn't return undefined. Though notice that if productId
is null and its if block doesn't execute - you tells your widget to build nothing - null, which is not possible. Consider simple else
clouse to handle it.
if (productId != null) {
final loadedProduct = Provider.of<Products>(context)
.items
.firstWhere((prod) => prod.id == productId);
return Scaffold(
appBar: AppBar(
title: Text(loadedProduct.title),
),
);
} else {
return Container()
}
CodePudding user response:
The Second Snippet will not work because you are not handling the return if the productId
is null
, so you have to always return something at the build()
method.
For the First Snippet, the problem is that the variable called loadedProduct
is defined inside the if condition
block, which is not accessed outside its scope, to solve the problem you can do the following steps:
- Define the variable
loadedProduct
outside theif condition
but not asfinal
, e.g. var loadedProduct; - Inside the
if condition
set the value of the variable, e.g.loadedProduct = Provider.of<Products>(context) ...
- By now, you have solved the problem if the
productId
is notnull
, but what if it isnull
?, then you have to think about theUI
at this case, you can simply set a defaulttitle
if theproductId
isnull
to better understand the case, e.g.Text(loadedProduct?.title ?? 'No Product Found')
NOTE:
loadedProduct?.title ?? 'No Product Found'
is equivalent to the following:
loadedProduct != null ? loadedProduct.title : 'No Product Found'
CodePudding user response:
loadedPorduct
is not available outside the if(productId!=null)
.
Place this variable out of it, inside the build context.
late final loadedProduct ;
final productId = ModalRoute.of(context)?.settings.arguments as String?;
if (productId != null) {
loadedProduct = Provider.of<Products>(context)
.items
.firstWhere((prod) => prod.id == productId);
}
And use case will be
Text(loadedProduct?.title?? "default TextOn null case"),