What is necessary the propagation operator(...), in this code flutter - flutter

I get this error when I attempt to compile:
The element type 'Iterable' can't be assigned to the list type 'Widget'.dartlist_element_type_not_assignable.
My code:
import 'package:flutter/material.dart';
import './question.dart';
import './answer.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
void _answerQuestion() {
setState(() {
_questionIndex = _questionIndex + 1;
print(_questionIndex);
});
}
#override
Widget build(BuildContext context) {
var questions = [
{
'question': 'what is your favourite color',
'answers': ['Black', 'Red', 'Green', 'white']
},
{
'question': 'what is your favourite song',
'answers': ['Thunderstorm', 'AC/DC', 'Mama mia', 'Burriqio']
},
{
'question': 'what is your favourite food',
'answers': ['Macarrones', 'Salmorejo', 'Albondigas', 'Chorizo']
}
];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Column(
children: [
Question(
questions[_questionIndex]['question'],
),
...(questions[_questionIndex]['answers'] as List<String>).map((answer) {
return Answer(_answerQuestion, answer);
})
],
),
),
);
}
}
I don't understand why I have to use that for add to list. Because isn't the operator for creating a new list with each element mapping with the method map?
Thank you if you can help me.

If you don't use spread operator(...), the result is nested list in your code.
Like below.
body: Column(
children: [
Widget1,
[Widget2, Widget3, ...],
],
),
When you use spread operator, the result will be list of Widget.
body: Column(
children: [
Widget1,
...[Widget2, Widget3, ...],
],
),
is same with below.
body: Column(
children: [
Widget1,
Widget2,
Widget3,
...,
],
),

Related

The method 'map' was called on null

I have a got a problem with the null, I have no idea why.. I'm begginer in the flutter
The method 'map' was called on null.
Receiver: null
Tried calling: map(Closure: (String) => Answer)"
main.dart
import 'package:flutter/material.dart';
import './question.dart';
import './answer.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
static const questions = [
{
'questionText': 'Whats your favourite car?',
'answers': ['HYUNDAI', 'BMW', 'KIA', 'AUDI']
},
{
'questionText': 'What is your favourite game?',
'answers': ['CS:GO', 'LOL', 'WOW', 'GTA']
},
{
'questionText': 'What is your favourite phone?',
'answer': ['IPHONE', 'SAMSUNG', 'SONY', 'HUAWEI']
}
];
var _questionIndex = 0;
void _answerQuestion() {
setState(() {
_questionIndex = _questionIndex + 1;
});
if (_questionIndex < questions.length) {
print('We have more questions');
}
print(_questionIndex);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text('Quiz App'),
),
body: _questionIndex < questions.length
? Column(
children: [
Question(
questions[_questionIndex]['questionText'] as String,
),
...(questions[_questionIndex]['answers'] as List<String>)
.map((answer) {
return Answer(_answerQuestion, answer);
}).toList(),
],
)
: Center(child: Text('We finally got it'))),
);
}
}
import 'package:flutter/material.dart';
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: Text(
questionText,
style: TextStyle(fontSize: 22),
textAlign: TextAlign.center,
),
);
}
}
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final VoidCallback selectHandler;
final String answerText;
Answer(this.selectHandler, this.answerText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
),
onPressed: selectHandler,
child: Text(answerText),
));
}
}
enter image description here
Please help me :)
I looked up on a different topics about this, adding ?? to toList () , but still the same error
static const questions = [
{
'questionText': 'Whats your favourite car?',
'answers': ['HYUNDAI', 'BMW', 'KIA', 'AUDI']
},
{
'questionText': 'What is your favourite game?',
'answers': ['CS:GO', 'LOL', 'WOW', 'GTA']
},
{
'questionText': 'What is your favourite phone?',
'answer': ['IPHONE', 'SAMSUNG', 'SONY', 'HUAWEI']
}
];
In the last item, you write answer instead of answers.
Please have a look!

How can I resolve "The argument type 'Object?' can't be assigned to the parameter type 'String'.dart(argument_type_not_assignable)"?

I am trying to access the values of questionText from questions.
When I am trying to extract String values from a map, the following error is displayed on Flutter. (The code is written in Dart):
The argument type 'Object?' can't be assigned to the parameter type
'String'.dart(argument_type_not_assignable)
Error:
This is my main.dart file:
import 'package:flutter/material.dart';
import './question.dart';
import './answer.dart';
// void main() {
// runApp(MyApp());
// }
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
void _answerQuestion() {
setState(() {
_questionIndex += 1;
});
print(_questionIndex);
}
#override
Widget build(BuildContext context) {
var questions = [
{
'questionText': 'What\'s your favorite color?',
'answers': ['Black', 'Red', 'Green', 'White'],
},
{
'questionText': 'What\'s your favorite animal?',
'answers': ['Rabbit', 'Snake', 'Elephant', 'Lion'],
},
{
'questionText': 'Who\'s your favorite instructor?',
'answers': ['Max', 'Max', 'Max', 'Max'],
},
];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Column(
children: [
Error on this line:
Question(
questions[_questionIndex]['questionText'],
),
Answer(_answerQuestion),
Answer(_answerQuestion),
Answer(_answerQuestion),
],
),
),
);
}
}
This is my question.dart file:
import 'package:flutter/material.dart';
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: Text(
questionText,
style: TextStyle(fontSize: 28),
textAlign: TextAlign.center,
),
);
}
}
You need to let dart know the type of questions[_questionIndex]['questionText']
Try this:
Change questions[_questionIndex]['questionText']
to questions[_questionIndex]['questionText'] as String
In the error line
Or You can rewrite as:
questions[_questionIndex]['questionText'] ?? ''
Replace question[_questionIndex]['questionText'] By question[_questionIndex]['questionText'] as String

The element type 'Question' can't be assigned to the list type 'Widget'

I can't use my own Class/Widget Question() from question.dart to main.dart (ERR Location 3rd line after body):
import 'package:flutter/material.dart';
import './question.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var questionIndex = 0;
// State of function that process data to UI
void _answerQuestion() {
setState(() {
questionIndex = questionIndex + 1;
});
print(questionIndex);
}
void _pangBawas() {
setState(() {
questionIndex = questionIndex - 1;
});
print(questionIndex);
}
// End of State
// This section is responsible for builing UI
#override
Widget build(BuildContext context) {
var questions = [
'What\'s your favorite color?',
'What\'s your favorite animal?',
'What\'s your favorite food?',
'What\'s your favorite color?',
'What\'s your favorite dress?',
'What\'s your favorite position?',
];
// Start of UI
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Column(
children: [
Question( //ERROR: The element type 'Question' can't be assigned to the list type 'Widget'.
questions[questionIndex],
),
RaisedButton(
child: Text('Answer 1'),
onPressed: _answerQuestion,
),
RaisedButton(
child: Text('Answer 2'),
onPressed: () => _pangBawas,
),
RaisedButton(
child: Text('Answer 3'),
onPressed: () {
//....
print('Hi');
}),
],
),
),
);
// End of UI
}
}
There's no error here, I only get error using Question() on my main.dart file
import 'package:/flutter/material.dart';
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
#override
Widget build(BuildContext context) {
return Container(
child: Text(
questionText,
),
);
}
}
Making use of interpolation solves some errors and displays the error to you in your UI. The code below works just fine:
import 'package:flutter/material.dart';
class Question extends StatelessWidget {
final String questiontext;
Question(this.questiontext);
#override
Widget build(BuildContext context) {
return Text("$questiontext");
}
}
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var questionIndex = 0;
// State of function that process data to UI
void _answerQuestion() {
setState(() {
questionIndex = questionIndex + 1;
});
print(questionIndex);
}
void _pangBawas() {
setState(() {
questionIndex = questionIndex - 1;
});
print(questionIndex);
}
// End of State
// This section is responsible for builing UI
#override
Widget build(BuildContext context) {
var questions = [
'What\'s your favorite color?',
'What\'s your favorite animal?',
'What\'s your favorite food?',
'What\'s your favorite color?',
'What\'s your favorite dress?',
'What\'s your favorite position?',
];
// Start of UI
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Column(
children: [
Question(
//ERROR: The element type 'Question' can't be assigned to the list type 'Widget'.
"${questions[questionIndex]}",
),
RaisedButton(
child: Text('Answer 1'),
onPressed: _answerQuestion,
),
RaisedButton(
child: Text('Answer 2'),
onPressed: () => _pangBawas,
),
RaisedButton(
child: Text('Answer 3'),
onPressed: () {
//....
print('Hi');
}),
],
),
),
);
// End of UI
}
}
You could add itinerary operator to check If the Widget that is returned from the Question class is null or not. This happens because the Column's children widgets can't be null.
body: Column(
children: [
Question(questions[questionIndex]) == null
? SizedBox()
: Question(questions[questionIndex]),
This way if the widget returned from the Question class is null, then the Column will create a SizedBox instead of the Container + Text.

Flutter / Dart / NoSuchMethodError

I have not been able to fix the error for 2 hours. Maybe one of you can help me. You can find a photo below.
What the Debug Console also tells me is:
[ The following NoSuchMethodError was thrown building MyApp (dirty, state: _MyAppState#c7f7e):
I/flutter (17681): The method 'map' was called on null.
I/flutter (17681): Receiver: null
I/flutter (17681): Tried calling: map<Answer>(Closure: (String) => Answer)]
import 'package:flutter/material.dart';
import './question.dart';
import './answer.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
void _answerQuestion() {
setState(() {
_questionIndex = _questionIndex + 1;
});
print(_questionIndex);
}
#override
Widget build(BuildContext context) {
const questions = const [
{
'questionText': 'What\'s your favorite color?',
'answer': ['Black', 'Yellow', 'white', 'green'],
},
{
'questionText': 'What\'s your favorite animal?',
'answer': ['Lion', 'Rabbit', 'Snake', 'Elephant'],
},
{
'questionText': 'What\'s your favorite instructor?',
'answer': ['Flo', 'Viona', 'Flint', 'Flo'],
},
];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App!'),
),
body: Column(
children: [
Question(
questions[_questionIndex]['questionText'],
),
...(questions[_questionIndex]['answers'] as List<String>)
.map((answer) {
return Answer(_answerQuestion, answer);
}).toList()
],
),
),
);
}
}
import 'package:flutter/material.dart';
//import './main.dart';
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: Text(
questionText,
style: TextStyle(fontSize: 28),
textAlign: TextAlign.center,
),
);
}
}
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final Function selectHandler;
final String answerText;
Answer(this.selectHandler, this.answerText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: RaisedButton(
color: Colors.blue,
textColor: Colors.white,
child: Text(answerText),
onPressed: selectHandler,
),
);
}
}
That shows me the app
There are no key called answers in your map. Instead it is called answer. So questions[_questionIndex]['answers'] will return null since the [] operator for Map is documented as:
Returns the value for the given key or null if key is not in the map.
https://api.dart.dev/stable/2.8.3/dart-core/Map/operator_get.html
Its due to higher Flutter version you are using. Do the change in pubspec.yaml file. Change the version to 2.11.0
environment:
sdk: ">=2.11.0 <3.0.0"

How to add dynamic buttons using a string in flutter

List list=["A","B","C","D"];
I want to add each char on a separate raised button.
How can I generate only 4 raised button and add these values on that button. Like,
mButton1="A";
.
.
.
mButtonN="n";
You can use the map operator
Column(
children: myCharList.map((String char){
return RaisedButton(child: Text(char)),
}).toList(),
),
main.dart full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<String> list = ["A", "B", "C", "D"];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Stack Overflow"),
),
body: Center(
child: Column(
children: list.map((String data) {
return RaisedButton(
child: Text(data),
onPressed: () {
print(data);
},
);
}).toList(),
),
),
),
);
}
}