A nullable expression can't be used as a condition

Viewed 9639

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,
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

2 Answers

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.

For more clarification about null safety issue just sharing some info here

There has 3 ways to handle null :

1. ?. Operator - value is Null or not by using simple syntax.

data?.varibale;

2. ?? Operator - has Null value and we can also pass default value like

variable ?? "";
    

3. ??= Operator - variable is Null or not. If the variable is Null then it will assign a new value to it

int x = 5;
x ??= 2;
    

Note : I have solved my same issue using ?. operator against bang(!)

May it help someone. Thanks

Related