A nullable expression can't be used as a condition

Issue

i’ve a problem with "nullable expression". The problem is in theese two lines: left: isSideBarOpenedAsync.data ? 0 : 0, and right: isSideBarOpenedAsync.data ? 0 : screenWidth - 35, i’m trying to open with an animation the sidebar menu. Some idea to fix that? Ty.

This is the error: Error: A value of type ‘bool?’ can’t be assigned to a variable of type ‘bool’ because ‘bool?’ is nullable and ‘bool’ isn’t.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:solaris/constants.dart';
import 'package:rxdart/rxdart.dart';

class SideBar extends StatefulWidget {

  @override
  _SideBarState createState() => _SideBarState();
}

class _SideBarState extends State<SideBar> with SingleTickerProviderStateMixin<SideBar>{
  late AnimationController _animationController;
  late StreamController<bool> isSidebarOpenedStreamController;
  late Stream<bool> isSideBarOpenedStream;
  late StreamSink<bool> isSideBarOpenedSink;
  final _animationDuration = const Duration(milliseconds: 500);

  @override
  void initState(){
    super.initState();
    _animationController = AnimationController(vsync: this, duration: _animationDuration);
    isSidebarOpenedStreamController = PublishSubject<bool>();
    isSideBarOpenedStream = isSidebarOpenedStreamController.stream;
    isSideBarOpenedSink = isSidebarOpenedStreamController.sink;
  }
  @override
  void dispose(){
  _animationController.dispose();
  isSidebarOpenedStreamController.close();
  isSideBarOpenedSink.close();
  super.dispose();
  }

  void onIconPressed(){
    final animationStatus = _animationController.status;
    final isAnimationCompleted = animationStatus == AnimationStatus.completed;

    if(isAnimationCompleted){
      isSideBarOpenedSink.add(false);
      _animationController.reverse();
    }else{
      isSideBarOpenedSink.add(true);
      _animationController.forward();
    }
  }

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;

    return StreamBuilder<bool>(
      initialData: false,
      stream: isSideBarOpenedStream,
      builder: (context, isSideBarOpenedAsync){
        return AnimatedPositioned(
          duration: _animationDuration,
          top: 0,
          bottom: 0,
          left: isSideBarOpenedAsync.data ? 0 : 0,
          right: isSideBarOpenedAsync.data ? 0 : screenWidth - 35,
          child: Row(
            children: <Widget>[
              Expanded(
                child: Container(
                  color: red,
                ),
              ),
              Align(
                alignment: Alignment(0,-0.9),
                child: GestureDetector(
                  onTap: (){
                    onIconPressed();
                  },
                  child: Container(
                    width: 35,
                    height: 110,
                    color: blue,
                    alignment: Alignment.centerLeft,
                    child: AnimatedIcon(
                      progress: _animationController.view,
                      icon: AnimatedIcons.menu_close,
                      color: white,
                      size: 25,
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

Solution

if you know that isSideBarOpenedAsync.data will always have data, you can use a ! to force the value to not be null.

for example:
isSideBarOpenedAsync.data!. This changes the value from bool? to bool. Your ternary expressions will work with this logic.

Note: if isSideBarOpenedAsync.data is in fact null and you have !, then you will get an error saying that bool cannot be type null.

if you don’t want this behavior, you can also provide a default value.

for example:

(isSideBarOpenedAsync.data ?? false)

In this case, if isSideBarOpenedAsync.data has a value, it will be referenced. If it is null, false will be used instead.

Answered By – mrgnhnt96

Answer Checked By – Marilyn (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.