0

good evening. I am currently doing a To-do List in Flutter and I want to pass the Title of my List and the Description of my List when I click on a new screen but upon setting up Routes and and declaring the values on my next, it shows the "2 positional arguments expected, but 0 found" on the routes I've set up. Here are my codes:

Here is my 1st screen:

import 'package:flutter/material.dart';
import 'package:todo_list/details.dart';
import 'package:todo_list/note.dart';

class MyApp extends StatelessWidget {
  final String text;
  final int number;
  final String listDescription;

  const MyApp(
      {super.key,
      required this.text,
      required this.number,
      required this.listDescription});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        DetailsPage.routeName: (ctx) => DetailsPage(),
      },
      home: CustomListTile(
        text: text,
        number: number,
        listDescription: listDescription,
      ),
    );
  }
}

class CustomListTile extends StatelessWidget {
  final String text;
  final int number;
  final String listDescription;

  const CustomListTile(
      {super.key,
      required this.text,
      required this.number,
      required this.listDescription});

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        Navigator.pushNamed(context, DetailsPage.routeName,
            arguments: Note(title: text, description: listDescription));
      },
      /* onTap: () {
        Widget okButton = TextButton(
          child: const Text("CLOSE"),
          onPressed: () {
            Navigator.of(context).pop();
          },
        );

        AlertDialog alert = AlertDialog(
            title: Text(text),
            content: Text('This item in the list contains $listDescription'),
            actions: [
              okButton,
            ]);
        showDialog(
            context: context,
            builder: (BuildContext context) {
              return alert;
            });
      }, */

      child: Padding(
        padding: const EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text("$number. $text",
                    style: const TextStyle(
                      fontSize: 20,
                    )),
                const Icon(Icons.chevron_right)
              ],
            ),
            Text(
              listDescription,
              style: const TextStyle(fontSize: 14, color: Colors.grey),
            ),
            const Divider()
          ],
        ),
      ),
    );
  }
}

and here is my 2nd screen:

import 'package:flutter/material.dart';

import 'note.dart';

class DetailsPage extends StatefulWidget {
  static const String routeName = "/details";
  final String text;
  final String listDescription;

  const DetailsPage(this.text, this.listDescription, {super.key});

 @override
  State<DetailsPage> createState() => _DetailsPageState();
}
class _DetailsPageState extends State<DetailsPage> {
 late Note params;
  @override
  void didChangeDependencies() {
    params = ModalRoute.of(context)!.settings.arguments! as Note;
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    Widget titleSection = Container(
      padding: const EdgeInsets.all(32),
      child: Row(
        children: [
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  padding: const EdgeInsets.only(bottom: 0),
                  child: Text(
                    params.title,
                    style: const TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 25,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );

    Color color = Theme.of(context).primaryColor;

    Widget buttonSection = Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        _buildButtonColumn(
          color,
          Icons.edit,
          'EDIT',
        ),
        _buildButtonColumn(color, Icons.delete, 'DELETE'),
      ],
    );

    Widget textSection = Padding(
      padding: const EdgeInsets.all(20),
      child: Text(
        params.description,
        softWrap: true,
      ),
    );

    return MaterialApp(
      title: 'Layout for a New Screen',
      theme: ThemeData(
        primarySwatch: Colors.brown,
      ),
      home: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: const Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
          title: Text(params.title),
        ),
        body: ListView(
          children: [
            Image.asset(
              'lib/images/placeholder.jpg',
              width: 600,
              height: 240,
              fit: BoxFit.cover,
            ),
            titleSection,
            buttonSection,
            textSection,
          ],
        ),
      ),
    );
  }

  Column _buildButtonColumn(
    Color color,
    IconData icon,
    String label,
  ) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Icon(icon, color: color),
        Container(
          margin: const EdgeInsets.only(top: 8),
          child: Text(
            label,
            style: TextStyle(
              fontSize: 12,
              fontWeight: FontWeight.w400,
              color: color,
            ),
          ),
        ),
      ],
    );
  }
}

    /* return Scaffold(
        appBar: AppBar(title: Text(text)),
        body: Center(
          child: Row(
            children: [Text(description)],
          ),
        ));
  }
} */ 

How do I make it so that the data I'll pass such as the Title and the Description will appear on the 2nd screen without the error "2 positional argument(s) expected, but 0 found. Try adding the missing arguments." appearing.

I tried the Quick Fixes on VS Code such as adding a const modifier but I think the const modifier wouldn't do a fix since both data I'm trying to pass are dynamic and may change from time to time.

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
c0rnelia
  • 13
  • 4

1 Answers1

0

As you've define details page

class DetailsPage extends StatefulWidget {
  static const String routeName = "/details";
  final String text;
  final String listDescription;

  const DetailsPage(this.text, this.listDescription, {super.key});

You need to pass two string as positional argument.

So it can be

routes: {
  DetailsPage.routeName: (ctx) => DetailsPage("text","description"),
},

also while you are using route arguments, you can remove theses from widget class and just accept from state class context with ModalRoute.

You can check this example and development/ui/navigation .

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
  • Thanks for this, Yeasin. There's just an error in the debug console stating "Exception caught by gesture. Could not find a generator for route RouteSettings("/details", Instance of 'Note') in the _WidgetsAppState." – c0rnelia Jan 07 '23 at 13:44
  • I think this issue is coming from `params = ModalRoute.of(context)!.settings.arguments! as Note;` 1st make nullable like `Note? params;` and then `params = ModalRoute.of(context)?.settings.arguments? as Note?;` – Md. Yeasin Sheikh Jan 07 '23 at 14:17
  • Do you have an example that I think I could read on how could I make this work? – c0rnelia Jan 08 '23 at 06:37
  • you follow my attached liks – Md. Yeasin Sheikh Jan 08 '23 at 09:11