Оператор проверки Flutter Null используется для нулевого значения даже после условной проверки нулевых значений
У меня есть проект Flutter + Riverpod, в котором я извлекаю некоторые данные при загрузке экрана. Получение ошибки оператора проверки Null, но я заранее проверяю, является ли значение нулевым или нет. Состояние имеет поле, допускающее значение NULLcurrentlyReading
который вначале равен нулю. Функция получения данных вызывается в конструкторе контроллера. Состояние корректно обновляется после выборки. Попытка отобразить пользовательский интерфейс условно на основе результата выборки, но возникает ошибка.
Контроллер, который извлекает данные и управляет состоянием:
final bookControllerProvider = StateNotifierProvider<BookController, BookState>(
(ref) => BookController(ref.read(bookRepositoryProvider), ref));
class BookState {
final Book? currentlyReading;
final List<Book>? books;
final bool isLoading;
final String? error;
BookState(
{this.currentlyReading,
this.books = const [],
this.isLoading = true,
this.error});
BookState copyWith({
Book? currentlyReading,
List<Book>? books,
bool? isLoading,
String? error,
}) {
return BookState(
currentlyReading: currentlyReading ?? this.currentlyReading,
books: books ?? this.books,
isLoading: isLoading ?? this.isLoading,
error: error ?? this.error,
);
}
}
class BookController extends StateNotifier<BookState> {
final BookRepository _bookRepository;
final Ref _ref;
BookController(this._bookRepository, this._ref) : super(BookState()) {
getCurrentlyReading();
}
void getCurrentlyReading() async {
state = state.copyWith(isLoading: true);
final user = _ref.read(userProvider);
final book = await _bookRepository.getBook(user!.readingBook!);
book.fold((l) {
state = state.copyWith(error: l.message, isLoading: false);
}, (userBook) {
state = state.copyWith(currentlyReading: userBook, isLoading: false);
});
}
}
Использование в пользовательском интерфейсе:
final user = ref.watch(userProvider)!;
final bookData = ref.watch(bookControllerProvider);
return Scaffold(
body: SafeArea(
child: Padding(
padding:
const EdgeInsets.only(top: 16.0, right: 16, bottom: 8, left: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 16),
Text(
'Currently Reading',
style: AppStyles.bodyText.copyWith(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Pallete.textGrey),
),
const SizedBox(height: 16),
bookData.isLoading
? const Expanded(child: Center(child: Loader()))
: bookData.currentlyReading == null
? const Text('Some error occurred')
: BookInfo(
book: bookData.currentlyReading!, height: deviceHeight)
],
),
),
));
Информация о книге:
class BookInfo extends StatelessWidget {
final Book book;
final double height;
const BookInfo({
Key? key,
required this.book,
required this.height,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image(
image: NetworkImage(book.thumbnail!),
),
SizedBox(
height: height * 0.01,
),
Text(book.title,
style: AppStyles.subtext.copyWith(
color: Pallete.primaryBlue, fontWeight: FontWeight.w500)),
Text('by ${book.authors.join(', ')}', style: AppStyles.bodyText),
],
);
}
}
Однако простойText
виджет, как показано ниже, работает при использовании вместоBookInfo
Text(bookData.currentlyReading!.title)
1 ответ
Ваша проблема не из-заbookData.currentlyReading
это произошло вBookInfo
виджет при попытке сборкиImage
виджет,book.thumbnail
может быть нулевым, и вы используете!
в теме:
book.thumbnail == null ? SizedBox() : Image(
image: NetworkImage(book.thumbnail!),
),