Cathal
Cathal

Reputation: 47

How do I fix the error: type '_InternalLinkedHashMap<String, List<dynamic>>' is not a subtype of type 'List<dynamic>'

Background

I'm building an app to help primary school teachers. This app allows the user to select letters from the alphabet and when they continue to the next screen the letters they select should show as flippable cards. One side has the letter, the other side has an image. These cards should take up the whole screen and the user can swipe to the next card.

The Issue

When the user selects multiple letters they are entered into a list. When they tap the button to move to the next screen (with the flippable cards) they are served the following error message:

"type '_InternalLinkedHashMap>' is not a subtype of type 'List'"

The Code

Below is the code for the letter selection screen:

import 'package:flutter/material.dart';
import 'package:project_teacher/pages/allcards.dart';

class ChooseLetters extends StatefulWidget {
  @override
  _ChooseLettersState createState() => _ChooseLettersState();
}

class _ChooseLettersState extends State<ChooseLetters> {

  List<String> alphabets = ['a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p',
    'q','r','s','t','u','v','w','x','y','z'],

      selection = [];

  List alphabetCards = [AlphabetCard(),BAlphabetCard(),CAlphabetCard(),DAlphabetCard(),EAlphabetCard(),FAlphabetCard(),
    GAlphabetCard(),HAlphabetCard(),IAlphabetCard(),JAlphabetCard(),KAlphabetCard(),LAlphabetCard(),MAlphabetCard(),NAlphabetCard(),OAlphabetCard(),PAlphabetCard(),
    QAlphabetCard(),RAlphabetCard(),SAlphabetCard(),TAlphabetCard(),UAlphabetCard(),VAlphabetCard(),WAlphabetCard(),XAlphabetCard(),YAlphabetCard(),ZAlphabetCard()],

      selectionCards = [];

  @override
  void initState(){
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
            gradient: LinearGradient(
                begin: Alignment.bottomLeft,
                end: Alignment.topRight,
                colors: [Colors.blueGrey[300], Colors.blueGrey])
        ),
        padding:EdgeInsets.all(15),
        alignment: Alignment.center,
        child:GridView.builder(
          gridDelegate:SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount:4,
            mainAxisSpacing: 10, crossAxisSpacing: 10,
          ),
          itemCount:alphabetCards.length,
          itemBuilder:(con,ind){
            return InkWell(
              onTap:(){
                setState((){
                  if(selectionCards.contains(alphabetCards[ind]))
                    selectionCards.remove(alphabetCards[ind]);
                  else
                    selectionCards.add(alphabetCards[ind]);
                });
                print(selectionCards);
              },
              child: Container(
                  padding:EdgeInsets.all(10),
                  alignment:Alignment.center,
                  decoration:BoxDecoration(
                      color:selectionCards.contains(alphabetCards[ind]) ? Colors.orange : Colors.white,
                      borderRadius:BorderRadius.circular(0)
                  ),
                  child:Text(alphabets[ind],
                      style: TextStyle(
                          color:Colors.black,
                          fontSize: 50
                      )
                  )
              ),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
          onPressed: () {
            Navigator.pushNamed(context, '/tabbedcards', arguments: {
              'selectionOfCards': selectionCards
            });
          },
        backgroundColor: Colors.red,
      ),
    );
  }

}

And this is the code for the flippable card screen:

import 'package:flutter/material.dart';

class TabbedCards extends StatefulWidget {

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

class _TabbedCardsState extends State<TabbedCards> {

  List selectionOfCards;

  @override
  Widget build(BuildContext context) {

    selectionOfCards = ModalRoute.of(context).settings.arguments;

    return MaterialApp(
      home: DefaultTabController(
        length: selectionOfCards.length,
        child: Scaffold(
          body: TabBarView(
            children: selectionOfCards
          ),
        ),
      ),
    );
  }
}

Thank you for reading and any help you may give.

Upvotes: 0

Views: 169

Answers (2)

Viren V Varasadiya
Viren V Varasadiya

Reputation: 27197

You have to make few change to make it work.

List<String> alphabets = ['a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p',
    'q','r','s','t','u','v','w','x','y','z'],

      selection = [];

here, you are trying to crate list of string and adding selection = [] ?

List<String> alphabets = ['a','b','c','d','e','f',
        'g','h','i','j','k','l','m','n','o','p',
        'q','r','s','t','u','v','w','x','y','z'];

Now Provide type to List of Widgets.

  List<Widget> alphabetCards = [
    AlphabetCard(),
    BAlphabetCard(),
    CAlphabetCard(),
    DAlphabetCard(),
    EAlphabetCard(),
     ....
  ];
  List<Widget> selectionCards = <Widget>[];

Now change your tab view as follow.

class _TabbedCardsState extends State<TabbedCards> {
  Map<String, List> selectionOfCards;
  List<Widget> data;

  @override
  Widget build(BuildContext context) {
    selectionOfCards = ModalRoute.of(context).settings.arguments;
    data = selectionOfCards['selectionOfCards'];
    print(data.toString());
    return MaterialApp(
      home: DefaultTabController(
        length: data.length,
        child: Scaffold(
          body: TabBarView(
            children: data,
          ),
        ),
      ),
    );
  }
}

Full Working demo Code:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',
      routes: {'/tabbedcards': (context) => TabbedCards()},
      home: ChooseLetters(),
    );
  }
}

class ChooseLetters extends StatefulWidget {
  @override
  _ChooseLettersState createState() => _ChooseLettersState();
}

class _ChooseLettersState extends State<ChooseLetters> {
  List<String> alphabets = [
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't',
    'u',
    'v',
    'w',
    'x',
    'y',
    'z'
  ];

  List<Widget> alphabetCards = [
    AlphabetCard(),
    BAlphabetCard(),
    CAlphabetCard(),
    DAlphabetCard(),
    EAlphabetCard(),
  ];
  List<Widget> selectionCards = <Widget>[];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
            gradient: LinearGradient(
                begin: Alignment.bottomLeft,
                end: Alignment.topRight,
                colors: [Colors.blueGrey[300], Colors.blueGrey])),
        padding: EdgeInsets.all(15),
        alignment: Alignment.center,
        child: GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4,
            mainAxisSpacing: 10,
            crossAxisSpacing: 10,
          ),
          itemCount: alphabetCards.length,
          itemBuilder: (con, ind) {
            return InkWell(
              onTap: () {
                setState(() {
                  print("print ${alphabetCards[ind].toString()}");
                  if (selectionCards.contains(alphabetCards[ind]))
                    selectionCards.remove(alphabetCards[ind]);
                  else
                    selectionCards.add(alphabetCards[ind]);
                });
                print(selectionCards);
              },
              child: Container(
                  padding: EdgeInsets.all(10),
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                      color: selectionCards.contains(alphabetCards[ind])
                          ? Colors.orange
                          : Colors.white,
                      borderRadius: BorderRadius.circular(0)),
                  child: Text(alphabets[ind],
                      style: TextStyle(color: Colors.black, fontSize: 50))),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.pushNamed(context, '/tabbedcards',
              arguments: {'selectionOfCards': selectionCards});
        },
        backgroundColor: Colors.red,
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(" A hello"),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(" B hello"),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(" C hello"),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(" D hello"),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(" E hello"),
    );
  }
}

class TabbedCards extends StatefulWidget {
  @override
  _TabbedCardsState createState() => _TabbedCardsState();
}

class _TabbedCardsState extends State<TabbedCards> {
  Map<String, List> selectionOfCards;
  List<Widget> data;

  @override
  Widget build(BuildContext context) {
    selectionOfCards = ModalRoute.of(context).settings.arguments;
    data = selectionOfCards['selectionOfCards'];
    print(data.toString());
    return MaterialApp(
      home: DefaultTabController(
        length: data.length,
        child: Scaffold(
          body: TabBarView(
            children: data,
          ),
        ),
      ),
    );
  }
}

Upvotes: 1

Peter Haddad
Peter Haddad

Reputation: 80944

Change this:

List selectionCards

Into this:

Map selectionCards

The arguments that you are retrieving here ModalRoute.of(context).settings.arguments is of type Map

Upvotes: 0

Related Questions