Why can not use map stream in Map object in dart languaje? - dart

By example has this code:
import 'package:flutter/material.dart';
class TableContent {
static Table render(BuildContext context, Map<String, String> rows) {
return Table(
border: const TableBorder(bottom: BorderSide(), horizontalInside: BorderSide()),
children: rows.map((title, message) => TableRow(
children: [
Text(
title,
style: Theme.of(context).textTheme.titleMedium
),
Text(message)
]
))
);
}
}
But says:
The argument type 'Map<dynamic, dynamic>' can't be assigned to the parameter type 'List'. (Documentation)
The map stream can not mutate type of return values like as a list. It is an error?

This solution is half cooked. You can tweak it a bit to reach the correct output.
class TableContent {
static Table render(BuildContext context, Map<String, String> rows) {
return Table(
border: const TableBorder(bottom: BorderSide(), horizontalInside: BorderSide()),
children: rows.entries.map((entry) {
return TableRow(children: [Text(entry['title'], style: Theme.of(context).textTheme.titleMedium), Text(entry['message'])]);
}).toList());
}
}
The issue is related to the type differences between what children: of table needs (a list) and what the .map() function returns which is (a Map)

Related

I can't use it without giving data to variables in dart classes

Code:
class Personel{
String ad;
String soyad;
int kidem;
String durum;
Personel(String ad, String soyad, int kidem){
this.ad = ad;
this.soyad = soyad;
this.kidem = kidem;
this.durum = durum;
}
}
Error:
: Error: Field 'ad' should be initialized because its type 'String' doesn't allow null.
lib/personeller.dart:2
String ad;
^^
: Error: Field 'soyad' should be initialized because its type 'String' doesn't allow null.
lib/personeller.dart:3
String soyad;
^^^^^
: Error: Field 'kidem' should be initialized because its type 'int' doesn't allow null.
lib/personeller.dart:4
int kidem;
^^^^^
What is the problem and how can I fix it? I am trying to use this code in flutter.
import 'package:flutter/material.dart';
import 'package:untitled1/personeller.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
List <Personel> personelListesi = [Personel("Levent", "Ertunalı", 13), Personel("Emir", "Bolat", 16), Personel("Ahmet", "Gaya", 21)];
return Scaffold(
appBar: AppBar(
title: Text("Personel Listesi"),
),
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: personelListesi.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(personelListesi[index].ad + " " + personelListesi[index].soyad),
subtitle: Text("Kıdem yılı: " + personelListesi[index].kidem.toString()),
trailing: Icon(Icons.done),
);
},
),
),
]
)
);
}}
My goal is to enter information into the list with the methods determined in the class. I will reflect the information I entered in the form of a list, there is no problem in Flutter codes, but I get an error in Class codes.
Change this:
class Personel{
String ad;
String soyad;
int kidem;
String durum;
Personel(String ad, String soyad, int kidem){
this.ad = ad;
this.soyad = soyad;
this.kidem = kidem;
this.durum = durum;
}
}
To this:
class Personel{
String ad;
String soyad;
int kidem;
String? durum;
Personel(this.ad, this.soyad, this.kidem);
}

Passing data between pages with bottom navigation bar in flutter

I have an app that routes to a "mainapp" page after logging in. This app contains a bottom navigation bar which displays pages of the corresponding pressed icon. I want to pass data of type Map<String, dynamic> to these pages but I am having trouble. This map is generated from a function that fetches the data from a server, saves it to shared preferences, then loads the shared preferences and returns it as a map (all contained in getData()). I want to pass this map around so I don't have to load shared preferences each time, but will also update this map along with shared preferences when needed( possibly an action on one of the pages).
class MainApp extends StatefulWidget {
#override
_MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
Map<String, dynamic> Data;
StartFunc() async {
Data = await getData();
setState(() {});
}
#override
void initState() {
StartFunc();
super.initState();
}
var _pages = [
PageOne(Data:Data),
PageTwo(),
PageThree(),
PageFour(),
PageFive(),
];
int _currentIndex = 0;
onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
#override
Widget build(BuildContext context) {
return _currentIndex == 2
? PageTwo()
: Scaffold(
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.library_books), title: Text('')),
BottomNavigationBarItem(
icon: Icon(Icons.notifications), title: Text('')),
BottomNavigationBarItem(
icon: Icon(Icons.add_circle_outline), title: Text('')),
BottomNavigationBarItem(
icon: Icon(Icons.mail), title: Text('')),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text('')),
],
onTap: onTabTapped,
currentIndex: _currentIndex,
),
);
}
}
I'm getting an error saying Only static members can be accessed in initializers. I was wondering if inherited widgets or other design patterns such as scoped model and BLoC can help but not sure if that's the right way to go. I'm also not sure how I would start implementing them in this case.
There are two problems in your code:
using an async method in the body of initState()
see here for details
using instance data in an initializer
see here for details
What follow is a very basic rewrite of your code, with minimal corrections.
The data map is loaded from a mocked backend, updated inside PageOne and printed to console in PageTwo onTap callback.
Please note that I've changed instance variable Data to data to be compliant with Effective Dart guidelines.
Note that the gist does not properly addresses the synchronization of the backend service with the shared preferences: this is something that have probably to be accounted in the final product.
I just commented what it is necessary to get your code works:
if the complexity of your system and the relations with external API start growing it could be worth considering a Bloc architecture.
import 'package:flutter/material.dart';
void main() => runApp(new MainApp());
// Mock up of an async backend service
Future<Map<String, dynamic>> getData() async {
return Future.delayed(Duration(seconds: 1), () => {'prop1': 'value1'});
}
class PageOne extends StatelessWidget {
final Map<String, dynamic> data;
PageOne({Key key, this.data}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: const Text('update preferences'),
onPressed: () {
data['prop2'] = 'value2';
},
),
);
}
}
class PageTwo extends StatelessWidget {
final Map<String, dynamic> data;
PageTwo({Key key, this.data}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: const Text('Got It!'),
onPressed: () {
print("data is now: [$data]");
},
),
);
}
}
class MainApp extends StatefulWidget {
#override
_MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
//Map<String, dynamic> Data;
Map<String, dynamic> data;
/*
StartFunc() async {
Data = await getData();
setState(() {});
}
*/
#override
void initState() {
//StartFunc();
super.initState();
getData().then((values) {
setState(() {
data = values;
});
});
}
/*
PageOne(data:data) is an invalid value for an initializer:
there is no way to access this at this point.
Initializers are executed before the constructor,
but this is only allowed to be accessed after the call
to the super constructor.
*/
/*
var _pages = [
PageOne(data:data),
PageTwo(),
];
*/
Widget getPage(int index) {
switch (index){
case 0:
return PageOne(data:data);
break;
case 1:
return PageTwo(data:data);
break;
default:
return PageOne();
break;
}
}
int _currentIndex = 0;
onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
#override
Widget build(BuildContext context) {
/*
return _currentIndex == 2
? PageTwo()
: Scaffold(
I use a MaterialApp because of material widgets (RaisedButton)
It is not mandatory, but it is mainstream in flutter
*/
return MaterialApp(
title: 'My App',
home: Scaffold(
appBar: AppBar(title: Text("My App Bar")),
body: getPage(_currentIndex),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.first_page), title: Text('')),
BottomNavigationBarItem(
icon: Icon(Icons.last_page), title: Text('')),
],
onTap: onTabTapped,
currentIndex: _currentIndex,
),
));
}
}

type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<Map<String, dynamic>>'

I'm little bit stuck on some situation.
1) type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<Map<String, dynamic>>'
My code.
List<Map<String, dynamic>> arrayOfProductList = List<Map<String, dynamic>>();
Calling APIs
Future<Map<String, dynamic>> _callWebServiceForGetProductList() async{
String strURL = 'http:xxxxxx/productlist.php';
Map<String, String> headerDic = {"Authorization": "ff624bc580ab48a3910d4352dxxx712"};
Map<String, String> paramDic = {"page": "1", "search": "", "term_id": ""};
http.Response httpRes = await http.post(strURL, headers: headerDic, body: paramDic);
Map<String, dynamic> responseDic = json.decode(httpRes.body);
return responseDic;
}
FutureBuilder Widget and stuff
Expanded(
child: Container(
child: FutureBuilder(
future: _callWebServiceForGetProductList(),
builder: (BuildContext context, AsyncSnapshot snap) {
if(snap.hasData) {
Map<String, dynamic> dicOfData = snap.data;
arrayOfProductList = dicOfData["data"] as List<Map<String, dynamic>>;
print(arrayOfProductList);
_setupProductListView();
}
else if(snap.hasError) {
showDialog(context: context, builder:(_) => AlertDialog(
content: Text("Error ${snap.hasError.toString()}"),
title: Text("Error"),
));
}
return Center(child: CircularProgressIndicator());
}
),
),
)
I'm googling for last 2 hours but didn't get any result. Where i'm going wrong? Guide me.
The cast attempt on dicOfData["data"] as List<Map<String, dynamic>> seems to have caused the type mismatch error you received. If you can provide more details on the data the snapshot contains, this can help us identify why it causes the error.

How to pass parameters to widgets in Flutter

I am opening a modal dialog in Flutter and wish to pass in a single parameter (postId) to the modal for further processing. But this is generating an error as shown.
class SharingDialog extends StatefulWidget {
#override
final String postId; // <--- generates the error, "Field doesn't override an inherited getter or setter"
SharingDialog({
String postId
}): this.postId = postId;
SharingDialogState createState() => new SharingDialogState(postId);
}
class SharingDialogState extends State<SharingDialog> {
SharingDialogState(this.postId);
final String postId;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar:
child: AppBar(
title: const Text('Share this Post'),
actions: [
new FlatButton(
onPressed: () {
print("Sharing Post ID: " + this.postId);
},
child: new Text('SHARE)
),
],
),
),
body: new Text("SHARING SCREEN"),
);
}
And then there is a click to open the modal using the following code which generates the accompanying error:
Code:
return new SharingDialog(postId);
Error: Too many positional arguments: 0 allowed, but 1 found.
How do you pass parameter(s) if not this way?
First:
Remove override keyword above postId
#override <-- this one
final String postId;
Second:
Because you are using named parameter , send the param like this way:
return new SharingDialog(postId: postId);
If you want more information about Optional named parameters, check this link:
https://www.dartlang.org/guides/language/language-tour#optional-parameters

Creating your own flutter widgets best practice

I am trying to understand the best style for creating your own widgets in flutter, and here are 2 very simplified examples
With the code at the bottom, I can use 1)
new SomeWidget("Some title", someFunction);
or 2)
SomeWidget.widget("Some title", someFunction);
or 3) Some other way I'm not aware of
Method 1) feels more correct (if I've not made some mistakes), however method 2) actually has less code (as I don't need to declare the object variables earlier, assuming I don't need access to context), but I'm wary of static methods.
Is 1) preferred, and why ?
class SomeWidget extends StatelesssWidget {
String title;
Function callback;
SomeWidget( this.title, this.callback );
//method 1
Widget build(context) {
return GestureDetector(
onTap: callback,
child: ....some widget
)
}
//method 2
static Widget widget(String title, Function callback) {
return GestureDetector(
onTap: callback,
child: ....some widget
)
}
}
I don't know actual guildelines, but I would prefer something like
class SomeWidget extends StatelesssWidget {
SomeWidget({this.title, this.callback});
final String title;
final VoidCallback callback;
Widget build(context) {
return GestureDetector(
onTap: callback,
child: ....some widget
);
}
}
or you can do like this
SomeWidget({this.title = '', #required this.callback})
for default values or if some value is reqired
P.S. All this is not guideline - it's just an IMHO )

Resources