Flutter Error - Null check operator used on null value (PDF viewer)

Viewed 446

Hello I am new in Flutter. When I compute this operation I got this error in my code. I have imported all the dependencies in my pubspec.yaml file. Please Help me.

Error

Null check operator used on a null value

fileview.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:offlinefileviewer/pdfapi.dart';
import 'package:offlinefileviewer/pdfviewerpage.dart';

class FileView extends StatelessWidget {
  const FileView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("File viewer"),
      ),
      body: ElevatedButton(
        onPressed: () async {
          final path = 'assets/pdf1.pdf';
          final file = await PdfApi.loadAsset(path);
          openPDF(context, file);
        },
        child: Text("Asset File"),
      ),
    );
  }

  void openPDF(BuildContext context, File file) => 
        Navigator.of(context).push(
        MaterialPageRoute(builder: (_) => PDFViewerPage(key: key!, file: file)),
      );
}

pdfviewerpage.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:path/path.dart';

class PDFViewerPage extends StatefulWidget {
  final File? file;

  const PDFViewerPage({
    Key? key,
    this.file,
  }) : super(key: key);

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

class _PDFViewerPageState extends State<PDFViewerPage> {
  PDFViewController? controller;
  int? pages;
  int? indexPage;

  @override
  Widget build(BuildContext context) {
    final name = basename(widget.file!.path);
    final text = '${indexPage! + 1} of $pages';

    return Scaffold(
      appBar: AppBar(
        title: Text(name),
        actions: pages! >= 2
            ? [
                Center(child: Text(text)),
                IconButton(
                  icon: Icon(Icons.chevron_left, size: 32),
                  onPressed: () {
                    final page = indexPage == 0 ? pages : indexPage! - 1;
                    controller!.setPage(page!);
                  },
                ),
                IconButton(
                  icon: Icon(Icons.chevron_right, size: 32),
                  onPressed: () {
                    final page = indexPage == pages! - 1 ? 0 : indexPage! + 1;
                    controller!.setPage(page);
                  },
                ),
              ]
            : null,
      ),
      body: PDFView(
        filePath: widget.file!.path,
        onRender: (pages) => setState(() => this.pages = pages!),
        onViewCreated: (controller) =>
            setState(() => this.controller = controller),
        onPageChanged: (indexPage, _) =>
            setState(() => this.indexPage = indexPage!),
      ),
    );
  }
}

Error

════════ Exception caught by widgets library ═══════════════════════════════════ The following _CastError was thrown building Builder(dirty): Null check operator used on a null value

The relevant error-causing widget was
MaterialApp
lib\main.dart:12
When the exception was thrown, this was the stack
#0      FileView.openPDF.<anonymous closure>
package:offlinefileviewer/fileview.dart:28
#1      MaterialPageRoute.buildContent
package:flutter/…/material/page.dart:53
#2      MaterialRouteTransitionMixin.buildPage
package:flutter/…/material/page.dart:106
#3      _ModalScopeState.build.<anonymous closure>.<anonymous closure>
package:flutter/…/widgets/routes.dart:843
#4      Builder.build
package:flutter/…/widgets/basic.dart:7798
...
════════════════════════════════════════════════════════════════════════════════
2 Answers

Avoid using nullable variables wherever when possible. So that it'll be safe and predictable by the analyzer itself.

  1. Avoid using ! operator whenever possible. See this.

However, you should be able to wrap each access to a nullable variable with an if condition to avoid continuing when it's null. When using ! it is strictly recommended to use some sort of check (preferably using if condition to see if the value is null or else do something that is expected to be done when the value is null)

class PDFViewerPage extends StatefulWidget {
  final File file;

  const PDFViewerPage({
    Key? key,
    required this.file,
  }) : super(key: key);

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

class _PDFViewerPageState extends State<PDFViewerPage> {
  PDFViewController? controller;
  int? pages;
  int? indexPage;

  late final String name;
  String get text => '${indexPage ?? 0 + 1} of ${pages ?? 0}';

  @override
  void initState() {
    name = basename(widget.file.path);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(name),
        actions: (pages ?? 0) >= 2 // edited
            ? [
                Center(child: Text(text)),
                IconButton(
                  icon: Icon(Icons.chevron_left, size: 32),
                  onPressed: () {
                    if (controller == null || pages == null) {
                      return;
                    }

                    final page =
                        (indexPage ?? 0) == 0 ? pages! : indexPage! - 1;

                    controller!.setPage(page);
                  },
                ),
                IconButton(
                  icon: Icon(Icons.chevron_right, size: 32),
                  onPressed: () {
                    if (controller == null || pages == null) {
                      return;
                    }

                    final page = (indexPage ?? 0) == pages! - 1
                        ? 0
                        : (indexPage ?? 0) + 1;

                    controller?.setPage(page);
                  },
                ),
              ]
            : null,
      ),
      body: PDFView(
        filePath: widget.file.path,
        onRender: (pages) => setState(() => this.pages = pages!),
        onViewCreated: (controller) =>
            setState(() => this.controller = controller),
        onPageChanged: (indexPage, _) =>
            setState(() => this.indexPage = indexPage!),
      ),
    );
  }
}
  1. In your fileview.dart the method openPdf, the key could be null. During runtime, it happened to be a null value, and ! operator was used which caused it to throw that exception.

Simply removing the ! operator, can solve the problem as PDFViewerPage accepts a nullable key parameter too.

This could help:

  void openPDF(BuildContext context, File file) => 
        Navigator.of(context).push(
        MaterialPageRoute(builder: (_) => PDFViewerPage(key: key, file: file)),
      );
  • remove async and try this below code
    
    
        ElevatedButton(
                      onPressed: () => openPDF(context, file),
                      child: Text("Asset File"),
                    )
    
    
      void openPDF(BuildContext context, File file) { 
                 final path = 'assets/pdf1.pdf';
                 final file = await PdfApi.loadAsset(path);
                Navigator.of(context).push(MaterialPageRoute(builder: (_) => PDFViewerPage(key: key!, file: file)));
       }
    

Related